GNUnet  0.10.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) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
39 
43 #define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
44 
48 #define NC_SIZE 16
49 
53 struct NamestoreClient;
54 
55 
60 {
65 
70 
75 
80 
85 
93  uint64_t seq;
94 
98  uint32_t request_id;
99 
107  uint32_t offset;
108 
113  unsigned int cache_ops;
114 
120  int send_end;
121 
122 };
123 
124 
129 {
130 
135 
140 
146 
152 };
153 
154 
159 {
163  struct ZoneMonitor *next;
164 
168  struct ZoneMonitor *prev;
169 
174 
179 
184 
189 
193  struct GNUNET_TIME_Absolute sa_waiting_start;
194 
202  uint64_t seq;
203 
208  uint64_t limit;
209 
216  uint64_t iteration_cnt;
217 
222 
230 
231 };
232 
233 
238 {
239 
244 
249 
254 
259 
264  struct ZoneIteration *zi;
265 
269  uint32_t rid;
270 };
271 
272 
278 {
283 
288 
293 
298  const struct RecordStoreMessage *rsm;
299 
304 
308  char *conv_name;
309 
310 };
311 
312 
316 struct NickCache
317 {
322 
327 
331  struct GNUNET_TIME_Absolute last_used;
332 };
333 
334 
338 static struct NickCache nick_cache[NC_SIZE];
339 
344 
349 
354 
359 
364 
368 static char *db_lib_name;
369 
373 static struct CacheOperation *cop_head;
374 
378 static struct CacheOperation *cop_tail;
379 
383 static struct ZoneMonitor *monitor_head;
384 
388 static struct ZoneMonitor *monitor_tail;
389 
393 static struct StoreActivity *sa_head;
394 
398 static struct StoreActivity *sa_tail;
399 
404 
409 static int cache_keys;
410 
415 static int disable_namecache;
416 
417 
423 static void
424 cleanup_task (void *cls)
425 {
426  struct CacheOperation *cop;
427 
428  (void) cls;
430  "Stopping namestore service\n");
431  while (NULL != (cop = cop_head))
432  {
434  "Aborting incomplete namecache operation\n");
436  GNUNET_CONTAINER_DLL_remove (cop_head,
437  cop_tail,
438  cop);
439  GNUNET_free (cop);
440  }
441  if (NULL != namecache)
442  {
443  GNUNET_NAMECACHE_disconnect (namecache);
444  namecache = NULL;
445  }
447  GSN_database));
449  db_lib_name = NULL;
450  if (NULL != monitor_nc)
451  {
453  monitor_nc = NULL;
454  }
455  if (NULL != statistics)
456  {
457  GNUNET_STATISTICS_destroy (statistics,
458  GNUNET_NO);
459  statistics = NULL;
460  }
461 }
462 
463 
469 static void
471 {
473  sa_tail,
474  sa);
475  GNUNET_free (sa->conv_name);
476  GNUNET_free (sa);
477 }
478 
479 
492 static void
493 lookup_nick_it (void *cls,
494  uint64_t seq,
495  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
496  const char *label,
497  unsigned int rd_count,
498  const struct GNUNET_GNSRECORD_Data *rd)
499 {
500  struct GNUNET_GNSRECORD_Data **res = cls;
501 
502  (void) private_key;
503  GNUNET_assert (0 != seq);
504  if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
505  {
506  GNUNET_break (0);
507  return;
508  }
509  for (unsigned int c = 0; c < rd_count; c++)
510  {
512  {
513  (*res) = GNUNET_malloc (rd[c].data_size + sizeof (struct GNUNET_GNSRECORD_Data));
514  (*res)->data = &(*res)[1];
515  GNUNET_memcpy ((void *) (*res)->data,
516  rd[c].data,
517  rd[c].data_size);
518  (*res)->data_size = rd[c].data_size;
519  (*res)->expiration_time = rd[c].expiration_time;
520  (*res)->flags = rd[c].flags;
521  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
522  return;
523  }
524  }
525  (*res) = NULL;
526 }
527 
528 
535 static void
537  const struct GNUNET_GNSRECORD_Data *nick)
538 {
539  struct NickCache *oldest;
540 
541  oldest = NULL;
542  for (unsigned int i=0;i<NC_SIZE;i++)
543  {
544  struct NickCache *pos = &nick_cache[i];
545 
546  if ( (NULL == oldest) ||
547  (oldest->last_used.abs_value_us >
548  pos->last_used.abs_value_us) )
549  oldest = pos;
550  if (0 == GNUNET_memcmp (zone,
551  &pos->zone))
552  {
553  oldest = pos;
554  break;
555  }
556  }
557  GNUNET_free_non_null (oldest->rd);
558  oldest->zone = *zone;
559  if (NULL != nick)
560  {
561  oldest->rd = GNUNET_malloc (sizeof (*nick) +
562  nick->data_size);
563  *oldest->rd = *nick;
564  oldest->rd->data = &oldest->rd[1];
565  memcpy (&oldest->rd[1],
566  nick->data,
567  nick->data_size);
568  }
569  else
570  {
571  oldest->rd = NULL;
572  }
573  oldest->last_used = GNUNET_TIME_absolute_get ();
574 }
575 
576 
583 static struct GNUNET_GNSRECORD_Data *
585 {
586  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
587  struct GNUNET_GNSRECORD_Data *nick;
588  int res;
589 
590  /* check cache first */
591  for (unsigned int i=0;i<NC_SIZE;i++)
592  {
593  struct NickCache *pos = &nick_cache[i];
594  if ( (NULL != pos->rd) &&
595  (0 == GNUNET_memcmp (zone,
596  &pos->zone)) )
597  {
598  if (NULL == pos->rd)
599  return NULL;
600  nick = GNUNET_malloc (sizeof (*nick) +
601  pos->rd->data_size);
602  *nick = *pos->rd;
603  nick->data = &nick[1];
604  memcpy (&nick[1],
605  pos->rd->data,
606  pos->rd->data_size);
608  return nick;
609  }
610  }
611 
612  nick = NULL;
613  res = GSN_database->lookup_records (GSN_database->cls,
614  zone,
617  &nick);
618  if ( (GNUNET_OK != res) ||
619  (NULL == nick) )
620  {
621  static int do_log = GNUNET_LOG_CALL_STATUS;
622 
623  if (0 == do_log)
624  do_log
626  "namestore",
627  __FILE__,
628  __FUNCTION__,
629  __LINE__);
630  if (1 == do_log)
631  {
634  "No nick name set for zone `%s'\n",
635  GNUNET_GNSRECORD_z2s (&pub));
636  }
637  /* update cache */
638  cache_nick (zone,
639  NULL);
640  return NULL;
641  }
642 
643  /* update cache */
644  cache_nick (zone,
645  nick);
646  return nick;
647 }
648 
649 
665 static void
667  unsigned int rd2_length,
668  const struct GNUNET_GNSRECORD_Data *rd2,
669  unsigned int *rdc_res,
670  struct GNUNET_GNSRECORD_Data **rd_res)
671 {
672  uint64_t latest_expiration;
673  size_t req;
674  char *data;
675  size_t data_offset;
676  struct GNUNET_GNSRECORD_Data *target;
677 
678  (*rdc_res) = 1 + rd2_length;
679  if (0 == 1 + rd2_length)
680  {
681  GNUNET_break (0);
682  (*rd_res) = NULL;
683  return;
684  }
685  req = sizeof (struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
686  for (unsigned int i=0; i<rd2_length; i++)
687  {
688  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
689 
690  if (req + sizeof (struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
691  {
692  GNUNET_break (0);
693  (*rd_res) = NULL;
694  return;
695  }
696  req += sizeof (struct GNUNET_GNSRECORD_Data) + orig->data_size;
697  }
698  target = GNUNET_malloc (req);
699  (*rd_res) = target;
700  data = (char *) &target[1 + rd2_length];
701  data_offset = 0;
702  latest_expiration = 0;
703  for (unsigned int i=0;i<rd2_length;i++)
704  {
705  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
706 
708  {
709  if ((GNUNET_TIME_absolute_get().abs_value_us + orig->expiration_time) >
710  latest_expiration)
711  latest_expiration = orig->expiration_time;
712  }
713  else if (orig->expiration_time > latest_expiration)
714  latest_expiration = orig->expiration_time;
715  target[i] = *orig;
716  target[i].data = (void *) &data[data_offset];
717  GNUNET_memcpy (&data[data_offset],
718  orig->data,
719  orig->data_size);
720  data_offset += orig->data_size;
721  }
722  /* append nick */
723  target[rd2_length] = *nick_rd;
724  target[rd2_length].expiration_time = latest_expiration;
725  target[rd2_length].data = (void *) &data[data_offset];
726  GNUNET_memcpy (&data[data_offset],
727  nick_rd->data,
728  nick_rd->data_size);
729  data_offset += nick_rd->data_size;
730  GNUNET_assert (req ==
731  (sizeof (struct GNUNET_GNSRECORD_Data)) * (*rdc_res) + data_offset);
732 }
733 
734 
746 static void
748  uint32_t request_id,
749  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
750  const char *name,
751  unsigned int rd_count,
752  const struct GNUNET_GNSRECORD_Data *rd)
753 {
754  struct GNUNET_MQ_Envelope *env;
755  struct RecordResultMessage *zir_msg;
756  struct GNUNET_GNSRECORD_Data *nick;
757  struct GNUNET_GNSRECORD_Data *res;
758  unsigned int res_count;
759  size_t name_len;
760  ssize_t rd_ser_len;
761  char *name_tmp;
762  char *rd_ser;
763 
764  nick = get_nick_record (zone_key);
765  GNUNET_assert (-1 !=
767  rd));
768 
769  if ( (NULL != nick) &&
770  (0 != strcmp (name,
772  {
775  rd_count,
776  rd,
777  &res_count,
778  &res);
779  GNUNET_free (nick);
780  }
781  else
782  {
783  res_count = rd_count;
784  res = (struct GNUNET_GNSRECORD_Data *) rd;
785  }
786 
787  GNUNET_assert (-1 !=
789  res));
790 
791 
792  name_len = strlen (name) + 1;
793  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count,
794  res);
795  if (rd_ser_len < 0)
796  {
797  GNUNET_break (0);
799  return;
800  }
801  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof (*zir_msg))
802  {
803  GNUNET_break (0);
805  return;
806  }
807  env = GNUNET_MQ_msg_extra (zir_msg,
808  name_len + rd_ser_len,
810  zir_msg->gns_header.r_id = htonl (request_id);
811  zir_msg->name_len = htons (name_len);
812  zir_msg->rd_count = htons (res_count);
813  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
814  zir_msg->private_key = *zone_key;
815  name_tmp = (char *) &zir_msg[1];
816  GNUNET_memcpy (name_tmp,
817  name,
818  name_len);
819  rd_ser = &name_tmp[name_len];
820  GNUNET_assert (rd_ser_len ==
822  res,
823  rd_ser_len,
824  rd_ser));
826  "Sending RECORD_RESULT message with %u records\n",
827  res_count);
828  GNUNET_STATISTICS_update (statistics,
829  "Record sets sent to clients",
830  1,
831  GNUNET_NO);
832  GNUNET_MQ_send (nc->mq,
833  env);
834  if (rd != res)
835  GNUNET_free (res);
836 }
837 
838 
846 static void
848  int res,
849  uint32_t rid)
850 {
851  struct GNUNET_MQ_Envelope *env;
852  struct RecordStoreResponseMessage *rcr_msg;
853 
854  GNUNET_assert (NULL != nc);
856  "Sending RECORD_STORE_RESPONSE message\n");
857  GNUNET_STATISTICS_update (statistics,
858  "Store requests completed",
859  1,
860  GNUNET_NO);
861  env = GNUNET_MQ_msg (rcr_msg,
863  rcr_msg->gns_header.r_id = htonl (rid);
864  rcr_msg->op_result = htonl (res);
865  GNUNET_MQ_send (nc->mq,
866  env);
867 }
868 
869 
876 static void
878 {
879  struct GNUNET_MQ_Envelope *env;
880  struct GNUNET_NAMESTORE_Header *em;
881 
883  if (! zi->send_end)
884  return;
885  /* send empty response to indicate end of list */
886  env = GNUNET_MQ_msg (em,
888  em->r_id = htonl (zi->request_id);
889  GNUNET_MQ_send (zi->nc->mq,
890  env);
891 
893  zi->nc->op_tail,
894  zi);
895  GNUNET_free (zi);
896 }
897 
898 
906 static void
908  int32_t success,
909  const char *emsg)
910 {
911  struct CacheOperation *cop = cls;
912  struct ZoneIteration *zi;
913 
914  if (NULL != emsg)
916  _("Failed to replicate block in namecache: %s\n"),
917  emsg);
918  else
920  "CACHE operation completed\n");
921  GNUNET_CONTAINER_DLL_remove (cop_head,
922  cop_tail,
923  cop);
924  if (NULL != cop->nc)
925  send_store_response (cop->nc,
926  success,
927  cop->rid);
928  if (NULL != (zi = cop->zi))
929  {
930  zi->cache_ops--;
931  if (0 == zi->cache_ops)
932  {
933  /* unchoke zone iteration, cache has caught up */
935  }
936  }
937  GNUNET_free (cop);
938 }
939 
940 
953 static void
955  struct ZoneIteration *zi,
956  uint32_t rid,
957  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
958  const char *name,
959  unsigned int rd_count,
960  const struct GNUNET_GNSRECORD_Data *rd)
961 {
962  struct GNUNET_GNSRECORD_Block *block;
963  struct CacheOperation *cop;
964  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
965  struct GNUNET_GNSRECORD_Data *nick;
966  struct GNUNET_GNSRECORD_Data *res;
967  unsigned int res_count;
968  struct GNUNET_TIME_Absolute exp_time;
969 
970  nick = get_nick_record (zone_key);
971  res_count = rd_count;
972  res = (struct GNUNET_GNSRECORD_Data *) rd; /* fixme: a bit unclean... */
973  if (NULL != nick)
974  {
977  rd_count,rd,
978  &res_count,
979  &res);
980  GNUNET_free (nick);
981  }
982  if (0 == res_count)
983  {
984  if (NULL != nc)
986  GNUNET_OK,
987  rid);
988  return; /* no data, no need to update cache */
989  }
991  {
992  GNUNET_STATISTICS_update (statistics,
993  "Namecache updates skipped (NC disabled)",
994  1,
995  GNUNET_NO);
996  if (NULL != nc)
998  GNUNET_OK,
999  rid);
1000  return;
1001  }
1002  exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count,
1003  res);
1004  if (cache_keys)
1005  block = GNUNET_GNSRECORD_block_create2 (zone_key,
1006  exp_time,
1007  name,
1008  res,
1009  res_count);
1010  else
1011  block = GNUNET_GNSRECORD_block_create (zone_key,
1012  exp_time,
1013  name,
1014  res,
1015  res_count);
1016  GNUNET_assert (NULL != block);
1018  &pkey);
1020  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
1021  name,
1022  res_count,
1024  GNUNET_GNSRECORD_z2s (&pkey));
1025  GNUNET_STATISTICS_update (statistics,
1026  "Namecache updates pushed",
1027  1,
1028  GNUNET_NO);
1029  cop = GNUNET_new (struct CacheOperation);
1030  cop->nc = nc;
1031  cop->zi = zi;
1032  if (NULL != zi)
1033  zi->cache_ops++;
1034  cop->rid = rid;
1035  GNUNET_CONTAINER_DLL_insert (cop_head,
1036  cop_tail,
1037  cop);
1038  cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
1039  block,
1041  cop);
1042  GNUNET_free (block);
1043 }
1044 
1045 
1051 static void
1053 {
1054  struct ZoneMonitor *zm = cls;
1055 
1057  "No response from monitor since %s\n",
1061  zm);
1062 }
1063 
1064 
1070 static void
1072 {
1073  const struct RecordStoreMessage *rp_msg = sa->rsm;
1074  unsigned int rd_count;
1075  size_t name_len;
1076  size_t rd_ser_len;
1077  uint32_t rid;
1078  const char *name_tmp;
1079  const char *rd_ser;
1080 
1081  rid = ntohl (rp_msg->gns_header.r_id);
1082  name_len = ntohs (rp_msg->name_len);
1083  rd_count = ntohs (rp_msg->rd_count);
1084  rd_ser_len = ntohs (rp_msg->rd_len);
1085  name_tmp = (const char *) &rp_msg[1];
1086  rd_ser = &name_tmp[name_len];
1087  {
1088  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)];
1089 
1090  /* We did this before, must succeed again */
1093  rd_ser,
1094  rd_count,
1095  rd));
1096 
1097  for (struct ZoneMonitor *zm = sa->zm_pos;
1098  NULL != zm;
1099  zm = sa->zm_pos)
1100  {
1101  if ( (0 != GNUNET_memcmp (&rp_msg->private_key,
1102  &zm->zone)) &&
1103  (0 != GNUNET_memcmp (&zm->zone,
1104  &zero)) )
1105  {
1106  sa->zm_pos = zm->next; /* not interesting to this monitor */
1107  continue;
1108  }
1109  if (zm->limit == zm->iteration_cnt)
1110  {
1111  zm->sa_waiting = GNUNET_YES;
1112  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
1113  if (NULL != zm->sa_wait_warning)
1114  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1117  zm);
1118  return; /* blocked on zone monitor */
1119  }
1121  "Notifying monitor about changes under label `%s'\n",
1122  sa->conv_name);
1123  zm->limit--;
1124  send_lookup_response (zm->nc,
1125  0,
1126  &rp_msg->private_key,
1127  sa->conv_name,
1128  rd_count,
1129  rd);
1130  sa->zm_pos = zm->next;
1131  }
1132  /* great, done with the monitors, unpack (again) for refresh_block operation */
1133  refresh_block (sa->nc,
1134  NULL,
1135  rid,
1136  &rp_msg->private_key,
1137  sa->conv_name,
1138  rd_count,
1139  rd);
1140  }
1142  free_store_activity (sa);
1143 }
1144 
1145 
1154 static void
1156  struct GNUNET_SERVICE_Client *client,
1157  void *app_ctx)
1158 {
1159  struct NamestoreClient *nc = app_ctx;
1160  struct ZoneIteration *no;
1161  struct CacheOperation *cop;
1162 
1163  (void) cls;
1165  "Client %p disconnected\n",
1166  client);
1167  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1168  {
1169  struct StoreActivity *san;
1170 
1171  if (nc != zm->nc)
1172  continue;
1173  GNUNET_CONTAINER_DLL_remove (monitor_head,
1174  monitor_tail,
1175  zm);
1176  if (NULL != zm->task)
1177  {
1178  GNUNET_SCHEDULER_cancel (zm->task);
1179  zm->task = NULL;
1180  }
1181  if (NULL != zm->sa_wait_warning)
1182  {
1183  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1184  zm->sa_wait_warning = NULL;
1185  }
1186  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1187  {
1188  san = sa->next;
1189  if (zm == sa->zm_pos)
1190  {
1191  sa->zm_pos = zm->next;
1192  /* this may free sa */
1194  }
1195  }
1196  GNUNET_free (zm);
1197  break;
1198  }
1199  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1200  {
1201  if (sa->nc == nc)
1202  {
1203  /* this may free sa */
1204  free_store_activity (sa);
1205  break; /* there can only be one per nc */
1206  }
1207  }
1208  while (NULL != (no = nc->op_head))
1209  {
1211  nc->op_tail,
1212  no);
1213  GNUNET_free (no);
1214  }
1215  for (cop = cop_head; NULL != cop; cop = cop->next)
1216  if (nc == cop->nc)
1217  cop->nc = NULL;
1218  GNUNET_free (nc);
1219 }
1220 
1221 
1230 static void *
1232  struct GNUNET_SERVICE_Client *client,
1233  struct GNUNET_MQ_Handle *mq)
1234 {
1235  struct NamestoreClient *nc;
1236 
1237  (void) cls;
1239  "Client %p connected\n",
1240  client);
1241  nc = GNUNET_new (struct NamestoreClient);
1242  nc->client = client;
1243  nc->mq = mq;
1244  return nc;
1245 }
1246 
1247 
1252 {
1253 
1257  const char *label;
1258 
1262  char *res_rd;
1263 
1268 
1272  int found;
1273 
1277  unsigned int res_rd_count;
1278 
1282  ssize_t rd_ser_len;
1283 };
1284 
1285 
1298 static void
1299 lookup_it (void *cls,
1300  uint64_t seq,
1301  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
1302  const char *label,
1303  unsigned int rd_count,
1304  const struct GNUNET_GNSRECORD_Data *rd)
1305 {
1306  struct RecordLookupContext *rlc = cls;
1307 
1308  (void) private_key;
1309  GNUNET_assert (0 != seq);
1310  if (0 != strcmp (label,
1311  rlc->label))
1312  return;
1313  rlc->found = GNUNET_YES;
1314  if (0 == rd_count)
1315  {
1316  rlc->rd_ser_len = 0;
1317  rlc->res_rd_count = 0;
1318  rlc->res_rd = NULL;
1319  return;
1320  }
1321  if ( (NULL != rlc->nick) &&
1322  (0 != strcmp (label,
1324  {
1325  /* Merge */
1326  struct GNUNET_GNSRECORD_Data *rd_res;
1327  unsigned int rdc_res;
1328 
1329  rd_res = NULL;
1330  rdc_res = 0;
1333  rd_count,
1334  rd,
1335  &rdc_res,
1336  &rd_res);
1338  rd_res);
1339  if (rlc->rd_ser_len < 0)
1340  {
1341  GNUNET_break (0);
1342  GNUNET_free (rd_res);
1343  rlc->found = GNUNET_NO;
1344  rlc->rd_ser_len = 0;
1345  return;
1346  }
1347  rlc->res_rd_count = rdc_res;
1348  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1349  if (rlc->rd_ser_len !=
1351  rd_res,
1352  rlc->rd_ser_len,
1353  rlc->res_rd))
1354  {
1355  GNUNET_break (0);
1356  GNUNET_free (rlc->res_rd);
1357  rlc->res_rd = NULL;
1358  rlc->res_rd_count = 0;
1359  rlc->rd_ser_len = 0;
1360  GNUNET_free (rd_res);
1361  rlc->found = GNUNET_NO;
1362  return;
1363  }
1364  GNUNET_free (rd_res);
1365  GNUNET_free (rlc->nick);
1366  rlc->nick = NULL;
1367  }
1368  else
1369  {
1371  rd);
1372  if (rlc->rd_ser_len < 0)
1373  {
1374  GNUNET_break (0);
1375  rlc->found = GNUNET_NO;
1376  rlc->rd_ser_len = 0;
1377  return;
1378  }
1379  rlc->res_rd_count = rd_count;
1380  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1381  if (rlc->rd_ser_len !=
1383  rd,
1384  rlc->rd_ser_len,
1385  rlc->res_rd))
1386  {
1387  GNUNET_break (0);
1388  GNUNET_free (rlc->res_rd);
1389  rlc->res_rd = NULL;
1390  rlc->res_rd_count = 0;
1391  rlc->rd_ser_len = 0;
1392  rlc->found = GNUNET_NO;
1393  return;
1394  }
1395  }
1396 }
1397 
1398 
1406 static int
1408  const struct LabelLookupMessage *ll_msg)
1409 {
1410  uint32_t name_len;
1411  size_t src_size;
1412 
1413  (void) cls;
1414  name_len = ntohl (ll_msg->label_len);
1415  src_size = ntohs (ll_msg->gns_header.header.size);
1416  if (name_len != src_size - sizeof (struct LabelLookupMessage))
1417  {
1418  GNUNET_break (0);
1419  return GNUNET_SYSERR;
1420  }
1422  return GNUNET_OK;
1423 }
1424 
1425 
1432 static void
1434  const struct LabelLookupMessage *ll_msg)
1435 {
1436  struct NamestoreClient *nc = cls;
1437  struct GNUNET_MQ_Envelope *env;
1438  struct LabelLookupResponseMessage *llr_msg;
1439  struct RecordLookupContext rlc;
1440  const char *name_tmp;
1441  char *res_name;
1442  char *conv_name;
1443  uint32_t name_len;
1444  int res;
1445 
1446  name_len = ntohl (ll_msg->label_len);
1447  name_tmp = (const char *) &ll_msg[1];
1450  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1451  name_tmp);
1452 
1453  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1454  if (NULL == conv_name)
1455  {
1457  "Error converting name `%s'\n",
1458  name_tmp);
1460  return;
1461  }
1462  rlc.label = conv_name;
1463  rlc.found = GNUNET_NO;
1464  rlc.res_rd_count = 0;
1465  rlc.res_rd = NULL;
1466  rlc.rd_ser_len = 0;
1467  rlc.nick = get_nick_record (&ll_msg->zone);
1468  res = GSN_database->lookup_records (GSN_database->cls,
1469  &ll_msg->zone,
1470  conv_name,
1471  &lookup_it,
1472  &rlc);
1473  GNUNET_free (conv_name);
1474  env = GNUNET_MQ_msg_extra (llr_msg,
1475  name_len + rlc.rd_ser_len,
1477  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1478  llr_msg->private_key = ll_msg->zone;
1479  llr_msg->name_len = htons (name_len);
1480  llr_msg->rd_count = htons (rlc.res_rd_count);
1481  llr_msg->rd_len = htons (rlc.rd_ser_len);
1482  res_name = (char *) &llr_msg[1];
1483  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
1484  llr_msg->found = ntohs (GNUNET_YES);
1485  else
1486  llr_msg->found = ntohs (GNUNET_NO);
1487  GNUNET_memcpy (&llr_msg[1],
1488  name_tmp,
1489  name_len);
1490  GNUNET_memcpy (&res_name[name_len],
1491  rlc.res_rd,
1492  rlc.rd_ser_len);
1493  GNUNET_MQ_send (nc->mq,
1494  env);
1496 }
1497 
1498 
1506 static int
1508  const struct RecordStoreMessage *rp_msg)
1509 {
1510  size_t name_len;
1511  size_t msg_size;
1512  size_t msg_size_exp;
1513  size_t rd_ser_len;
1514  const char *name_tmp;
1515 
1516  (void) cls;
1517  name_len = ntohs (rp_msg->name_len);
1518  msg_size = ntohs (rp_msg->gns_header.header.size);
1519  rd_ser_len = ntohs (rp_msg->rd_len);
1520  msg_size_exp = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len;
1521  if (msg_size != msg_size_exp)
1522  {
1523  GNUNET_break (0);
1524  return GNUNET_SYSERR;
1525  }
1526  if ( (0 == name_len) ||
1527  (name_len > MAX_NAME_LEN) )
1528  {
1529  GNUNET_break (0);
1530  return GNUNET_SYSERR;
1531  }
1532  name_tmp = (const char *) &rp_msg[1];
1533  if ('\0' != name_tmp[name_len -1])
1534  {
1535  GNUNET_break (0);
1536  return GNUNET_SYSERR;
1537  }
1538  return GNUNET_OK;
1539 }
1540 
1541 
1548 static void
1550  const struct RecordStoreMessage *rp_msg)
1551 {
1552  struct NamestoreClient *nc = cls;
1553  size_t name_len;
1554  size_t rd_ser_len;
1555  uint32_t rid;
1556  const char *name_tmp;
1557  char *conv_name;
1558  const char *rd_ser;
1559  unsigned int rd_count;
1560  int res;
1561  struct StoreActivity *sa;
1562 
1564  "Received NAMESTORE_RECORD_STORE message\n");
1565  rid = ntohl (rp_msg->gns_header.r_id);
1566  name_len = ntohs (rp_msg->name_len);
1567  rd_count = ntohs (rp_msg->rd_count);
1568  rd_ser_len = ntohs (rp_msg->rd_len);
1569  GNUNET_break (0 == ntohs (rp_msg->reserved));
1570  name_tmp = (const char *) &rp_msg[1];
1571  rd_ser = &name_tmp[name_len];
1572  {
1573  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)];
1574 
1575  if (GNUNET_OK !=
1577  rd_ser,
1578  rd_count,
1579  rd))
1580  {
1581  GNUNET_break (0);
1583  return;
1584  }
1585 
1586  /* Extracting and converting private key */
1587  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1588  if (NULL == conv_name)
1589  {
1591  "Error converting name `%s'\n",
1592  name_tmp);
1594  return;
1595  }
1596  GNUNET_STATISTICS_update (statistics,
1597  "Well-formed store requests received",
1598  1,
1599  GNUNET_NO);
1601  "Creating %u records for name `%s'\n",
1602  (unsigned int) rd_count,
1603  conv_name);
1604  if ( (0 == rd_count) &&
1605  (GNUNET_NO ==
1606  GSN_database->lookup_records (GSN_database->cls,
1607  &rp_msg->private_key,
1608  conv_name,
1609  NULL,
1610  0)) )
1611  {
1612  /* This name does not exist, so cannot be removed */
1614  "Name `%s' does not exist, no deletion required\n",
1615  conv_name);
1616  res = GNUNET_NO;
1617  }
1618  else
1619  {
1620  /* remove "NICK" records, unless this is for the
1621  #GNUNET_GNS_EMPTY_LABEL_AT label */
1622  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL(rd_count)];
1623  unsigned int rd_clean_off;
1624  int have_nick;
1625 
1626  rd_clean_off = 0;
1627  have_nick = GNUNET_NO;
1628  for (unsigned int i=0;i<rd_count;i++)
1629  {
1630  rd_clean[rd_clean_off] = rd[i];
1631  if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1632  conv_name)) ||
1634  rd_clean_off++;
1635 
1636  if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1637  conv_name)) &&
1638  (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) )
1639  {
1640  cache_nick (&rp_msg->private_key,
1641  &rd[i]);
1642  have_nick = GNUNET_YES;
1643  }
1644  }
1645  if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1646  conv_name)) &&
1647  (GNUNET_NO == have_nick) )
1648  {
1649  /* remove nick record from cache, in case we have one there */
1650  cache_nick (&rp_msg->private_key,
1651  NULL);
1652  }
1653  res = GSN_database->store_records (GSN_database->cls,
1654  &rp_msg->private_key,
1655  conv_name,
1656  rd_clean_off,
1657  rd_clean);
1658  }
1659 
1660  if (GNUNET_OK != res)
1661  {
1662  /* store not successful, not need to tell monitors */
1663  send_store_response (nc,
1664  res,
1665  rid);
1667  GNUNET_free (conv_name);
1668  return;
1669  }
1670 
1671  sa = GNUNET_malloc (sizeof (struct StoreActivity) +
1672  ntohs (rp_msg->gns_header.header.size));
1673  GNUNET_CONTAINER_DLL_insert (sa_head,
1674  sa_tail,
1675  sa);
1676  sa->nc = nc;
1677  sa->rsm = (const struct RecordStoreMessage *) &sa[1];
1678  GNUNET_memcpy (&sa[1],
1679  rp_msg,
1680  ntohs (rp_msg->gns_header.header.size));
1681  sa->zm_pos = monitor_head;
1682  sa->conv_name = conv_name;
1684  }
1685 }
1686 
1687 
1693 {
1698 
1702  uint32_t rid;
1703 
1709  int success;
1710 };
1711 
1712 
1723 static void
1725  uint64_t seq,
1726  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1727  const char *name,
1728  unsigned int rd_count,
1729  const struct GNUNET_GNSRECORD_Data *rd)
1730 {
1731  struct ZoneToNameCtx *ztn_ctx = cls;
1732  struct GNUNET_MQ_Envelope *env;
1733  struct ZoneToNameResponseMessage *ztnr_msg;
1734  int16_t res;
1735  size_t name_len;
1736  ssize_t rd_ser_len;
1737  size_t msg_size;
1738  char *name_tmp;
1739  char *rd_tmp;
1740 
1741  GNUNET_assert (0 != seq);
1743  "Found result for zone-to-name lookup: `%s'\n",
1744  name);
1745  res = GNUNET_YES;
1746  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1747  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count,
1748  rd);
1749  if (rd_ser_len < 0)
1750  {
1751  GNUNET_break (0);
1752  ztn_ctx->success = GNUNET_SYSERR;
1753  return;
1754  }
1755  msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1756  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1757  {
1758  GNUNET_break (0);
1759  ztn_ctx->success = GNUNET_SYSERR;
1760  return;
1761  }
1762  env = GNUNET_MQ_msg_extra (ztnr_msg,
1763  name_len + rd_ser_len,
1765  ztnr_msg->gns_header.header.size = htons (msg_size);
1766  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1767  ztnr_msg->res = htons (res);
1768  ztnr_msg->rd_len = htons (rd_ser_len);
1769  ztnr_msg->rd_count = htons (rd_count);
1770  ztnr_msg->name_len = htons (name_len);
1771  ztnr_msg->zone = *zone_key;
1772  name_tmp = (char *) &ztnr_msg[1];
1773  GNUNET_memcpy (name_tmp,
1774  name,
1775  name_len);
1776  rd_tmp = &name_tmp[name_len];
1777  GNUNET_assert (rd_ser_len ==
1779  rd,
1780  rd_ser_len,
1781  rd_tmp));
1782  ztn_ctx->success = GNUNET_OK;
1783  GNUNET_MQ_send (ztn_ctx->nc->mq,
1784  env);
1785 }
1786 
1787 
1794 static void
1796  const struct ZoneToNameMessage *ztn_msg)
1797 {
1798  struct NamestoreClient *nc = cls;
1799  struct ZoneToNameCtx ztn_ctx;
1800  struct GNUNET_MQ_Envelope *env;
1801  struct ZoneToNameResponseMessage *ztnr_msg;
1802 
1804  "Received ZONE_TO_NAME message\n");
1805  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
1806  ztn_ctx.nc = nc;
1807  ztn_ctx.success = GNUNET_NO;
1808  if (GNUNET_SYSERR ==
1809  GSN_database->zone_to_name (GSN_database->cls,
1810  &ztn_msg->zone,
1811  &ztn_msg->value_zone,
1812  &handle_zone_to_name_it, &ztn_ctx))
1813  {
1814  /* internal error, hang up instead of signalling something
1815  that might be wrong */
1816  GNUNET_break (0);
1818  return;
1819  }
1820  if (GNUNET_NO == ztn_ctx.success)
1821  {
1822  /* no result found, send empty response */
1824  "Found no result for zone-to-name lookup.\n");
1825  env = GNUNET_MQ_msg (ztnr_msg,
1827  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
1828  ztnr_msg->res = htons (GNUNET_NO);
1829  GNUNET_MQ_send (nc->mq,
1830  env);
1831  }
1833 }
1834 
1835 
1841 {
1846 
1850  uint64_t limit;
1851 
1852 };
1853 
1854 
1865 static void
1867  uint64_t seq,
1868  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1869  const char *name,
1870  unsigned int rd_count,
1871  const struct GNUNET_GNSRECORD_Data *rd)
1872 {
1873  struct ZoneIterationProcResult *proc = cls;
1874  int do_refresh_block;
1875 
1876  GNUNET_assert (0 != seq);
1877  if ( (NULL == zone_key) &&
1878  (NULL == name) )
1879  {
1881  "Iteration done\n");
1882  return;
1883  }
1884  if ( (NULL == zone_key) ||
1885  (NULL == name) )
1886  {
1887  /* what is this!? should never happen */
1888  GNUNET_break (0);
1889  return;
1890  }
1891  if (0 == proc->limit)
1892  {
1893  /* what is this!? should never happen */
1894  GNUNET_break (0);
1895  return;
1896  }
1897  proc->limit--;
1898  proc->zi->seq = seq;
1899  send_lookup_response (proc->zi->nc,
1900  proc->zi->request_id,
1901  zone_key,
1902  name,
1903  rd_count,
1904  rd);
1905 
1906 
1907  do_refresh_block = GNUNET_NO;
1908  for (unsigned int i=0;i<rd_count;i++)
1909  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1910  {
1911  do_refresh_block = GNUNET_YES;
1912  break;
1913  }
1914  if (GNUNET_YES == do_refresh_block)
1915  refresh_block (NULL,
1916  proc->zi,
1917  0,
1918  zone_key,
1919  name,
1920  rd_count,
1921  rd);
1922 }
1923 
1924 
1931 static void
1933  uint64_t limit)
1934 {
1935  struct ZoneIterationProcResult proc;
1936  struct GNUNET_TIME_Absolute start;
1937  struct GNUNET_TIME_Relative duration;
1938 
1939  memset (&proc,
1940  0,
1941  sizeof (proc));
1943  "Asked to return up to %llu records at position %llu\n",
1944  (unsigned long long) limit,
1945  (unsigned long long) zi->seq);
1946  proc.zi = zi;
1947  proc.limit = limit;
1948  start = GNUNET_TIME_absolute_get ();
1950  GSN_database->iterate_records (GSN_database->cls,
1951  (0 == GNUNET_is_zero (&zi->zone))
1952  ? NULL
1953  : &zi->zone,
1954  zi->seq,
1955  limit,
1957  &proc));
1958  duration = GNUNET_TIME_absolute_get_duration (start);
1959  duration = GNUNET_TIME_relative_divide (duration,
1960  limit - proc.limit);
1961  GNUNET_STATISTICS_set (statistics,
1962  "NAMESTORE iteration delay (μs/record)",
1963  duration.rel_value_us,
1964  GNUNET_NO);
1965  if (0 == proc.limit)
1967  "Returned %llu results, more results available\n",
1968  (unsigned long long) limit);
1969  zi->send_end = (0 != proc.limit);
1970  if (0 == zi->cache_ops)
1972 }
1973 
1974 
1981 static void
1983  const struct ZoneIterationStartMessage *zis_msg)
1984 {
1985  struct NamestoreClient *nc = cls;
1986  struct ZoneIteration *zi;
1987 
1989  "Received ZONE_ITERATION_START message\n");
1990  zi = GNUNET_new (struct ZoneIteration);
1991  zi->request_id = ntohl (zis_msg->gns_header.r_id);
1992  zi->offset = 0;
1993  zi->nc = nc;
1994  zi->zone = zis_msg->zone;
1995 
1997  nc->op_tail,
1998  zi);
2000  1);
2001 }
2002 
2003 
2010 static void
2012  const struct ZoneIterationStopMessage *zis_msg)
2013 {
2014  struct NamestoreClient *nc = cls;
2015  struct ZoneIteration *zi;
2016  uint32_t rid;
2017 
2019  "Received ZONE_ITERATION_STOP message\n");
2020  rid = ntohl (zis_msg->gns_header.r_id);
2021  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2022  if (zi->request_id == rid)
2023  break;
2024  if (NULL == zi)
2025  {
2026  GNUNET_break (0);
2028  return;
2029  }
2031  nc->op_tail,
2032  zi);
2033  GNUNET_free (zi);
2035 }
2036 
2037 
2044 static void
2046  const struct ZoneIterationNextMessage *zis_msg)
2047 {
2048  struct NamestoreClient *nc = cls;
2049  struct ZoneIteration *zi;
2050  uint32_t rid;
2051  uint64_t limit;
2052 
2054  "Received ZONE_ITERATION_NEXT message\n");
2055  GNUNET_STATISTICS_update (statistics,
2056  "Iteration NEXT messages received",
2057  1,
2058  GNUNET_NO);
2059  rid = ntohl (zis_msg->gns_header.r_id);
2060  limit = GNUNET_ntohll (zis_msg->limit);
2061  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2062  if (zi->request_id == rid)
2063  break;
2064  if (NULL == zi)
2065  {
2066  GNUNET_break (0);
2068  return;
2069  }
2071  limit);
2072 }
2073 
2074 
2080 static void
2082 {
2083  struct StoreActivity *sa = sa_head;
2084 
2085  while ( (NULL != sa) &&
2086  (zm->limit > zm->iteration_cnt) )
2087  {
2088  struct StoreActivity *sn = sa->next;
2089 
2090  if (sa->zm_pos == zm)
2092  sa = sn;
2093  }
2094  if (zm->limit > zm->iteration_cnt)
2095  {
2096  zm->sa_waiting = GNUNET_NO;
2097  if (NULL != zm->sa_wait_warning)
2098  {
2100  zm->sa_wait_warning = NULL;
2101  }
2102  }
2103  else if (GNUNET_YES == zm->sa_waiting)
2104  {
2106  if (NULL != zm->sa_wait_warning)
2110  zm);
2111  }
2112 }
2113 
2114 
2120 static void
2122 {
2123  struct GNUNET_MQ_Envelope *env;
2124  struct GNUNET_MessageHeader *sync;
2125 
2126  env = GNUNET_MQ_msg (sync,
2128  GNUNET_MQ_send (zm->nc->mq,
2129  env);
2130  /* mark iteration done */
2132  zm->iteration_cnt = 0;
2133  if ( (zm->limit > 0) &&
2134  (zm->sa_waiting) )
2135  monitor_unblock (zm);
2136 }
2137 
2138 
2144 static void
2145 monitor_iteration_next (void *cls);
2146 
2147 
2158 static void
2160  uint64_t seq,
2161  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
2162  const char *name,
2163  unsigned int rd_count,
2164  const struct GNUNET_GNSRECORD_Data *rd)
2165 {
2166  struct ZoneMonitor *zm = cls;
2167 
2168  GNUNET_assert (0 != seq);
2169  zm->seq = seq;
2170  GNUNET_assert (NULL != name);
2171  GNUNET_STATISTICS_update (statistics,
2172  "Monitor notifications sent",
2173  1,
2174  GNUNET_NO);
2175  zm->limit--;
2176  zm->iteration_cnt--;
2177  send_lookup_response (zm->nc,
2178  0,
2179  zone_key,
2180  name,
2181  rd_count,
2182  rd);
2183  if ( (0 == zm->iteration_cnt) &&
2184  (0 != zm->limit) )
2185  {
2186  /* We are done with the current iteration batch, AND the
2187  client would right now accept more, so go again! */
2188  GNUNET_assert (NULL == zm->task);
2190  zm);
2191  }
2192 }
2193 
2194 
2201 static void
2203  const struct ZoneMonitorStartMessage *zis_msg)
2204 {
2205  struct NamestoreClient *nc = cls;
2206  struct ZoneMonitor *zm;
2207 
2209  "Received ZONE_MONITOR_START message\n");
2210  zm = GNUNET_new (struct ZoneMonitor);
2211  zm->nc = nc;
2212  zm->zone = zis_msg->zone;
2213  zm->limit = 1;
2214  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2215  GNUNET_CONTAINER_DLL_insert (monitor_head,
2216  monitor_tail,
2217  zm);
2220  GNUNET_notification_context_add (monitor_nc,
2221  nc->mq);
2222  if (zm->in_first_iteration)
2224  zm);
2225  else
2226  monitor_sync (zm);
2227 }
2228 
2229 
2235 static void
2237 {
2238  struct ZoneMonitor *zm = cls;
2239  int ret;
2240 
2241  zm->task = NULL;
2242  GNUNET_assert (0 == zm->iteration_cnt);
2243  if (zm->limit > 16)
2244  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2245  else
2246  zm->iteration_cnt = zm->limit; /* use it all */
2247  ret = GSN_database->iterate_records (GSN_database->cls,
2248  (0 == GNUNET_is_zero (&zm->zone))
2249  ? NULL
2250  : &zm->zone,
2251  zm->seq,
2252  zm->iteration_cnt,
2254  zm);
2255  if (GNUNET_SYSERR == ret)
2256  {
2258  return;
2259  }
2260  if (GNUNET_NO == ret)
2261  {
2262  /* empty zone */
2263  monitor_sync (zm);
2264  return;
2265  }
2266 }
2267 
2268 
2275 static void
2277  const struct ZoneMonitorNextMessage *nm)
2278 {
2279  struct NamestoreClient *nc = cls;
2280  struct ZoneMonitor *zm;
2281  uint64_t inc;
2282 
2283  inc = GNUNET_ntohll (nm->limit);
2285  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2286  (unsigned long long) inc);
2287  for (zm = monitor_head; NULL != zm; zm = zm->next)
2288  if (zm->nc == nc)
2289  break;
2290  if (NULL == zm)
2291  {
2292  GNUNET_break (0);
2294  return;
2295  }
2297  if (zm->limit + inc < zm->limit)
2298  {
2299  GNUNET_break (0);
2301  return;
2302  }
2303  zm->limit += inc;
2304  if ( (zm->in_first_iteration) &&
2305  (zm->limit == inc) )
2306  {
2307  /* We are still iterating, and the previous iteration must
2308  have stopped due to the client's limit, so continue it! */
2309  GNUNET_assert (NULL == zm->task);
2311  zm);
2312  }
2313  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2314  if ( (zm->limit > zm->iteration_cnt) &&
2315  (zm->sa_waiting) )
2316  {
2317  monitor_unblock (zm);
2318  }
2319  else if (GNUNET_YES == zm->sa_waiting)
2320  {
2321  if (NULL != zm->sa_wait_warning)
2326  zm);
2327  }
2328 }
2329 
2330 
2338 static void
2339 run (void *cls,
2340  const struct GNUNET_CONFIGURATION_Handle *cfg,
2342 {
2343  char *database;
2344 
2345  (void) cls;
2346  (void) service;
2348  "Starting namestore service\n");
2350  "namestore",
2351  "CACHE_KEYS");
2353  "namecache",
2354  "DISABLE");
2355  GSN_cfg = cfg;
2356  monitor_nc = GNUNET_notification_context_create (1);
2358  {
2359  namecache = GNUNET_NAMECACHE_connect (cfg);
2360  GNUNET_assert (NULL != namecache);
2361  }
2362  /* Loading database plugin */
2363  if (GNUNET_OK !=
2365  "namestore",
2366  "database",
2367  &database))
2369  "No database backend configured\n");
2370 
2372  "libgnunet_plugin_namestore_%s",
2373  database);
2374  GSN_database = GNUNET_PLUGIN_load (db_lib_name,
2375  (void *) GSN_cfg);
2376  GNUNET_free (database);
2377  statistics = GNUNET_STATISTICS_create ("namestore",
2378  cfg);
2380  NULL);
2381  if (NULL == GSN_database)
2382  {
2384  "Could not load database backend `%s'\n",
2385  db_lib_name);
2387  return;
2388  }
2389 }
2390 
2391 
2396 ("namestore",
2398  &run,
2401  NULL,
2402  GNUNET_MQ_hd_var_size (record_store,
2404  struct RecordStoreMessage,
2405  NULL),
2406  GNUNET_MQ_hd_var_size (record_lookup,
2408  struct LabelLookupMessage,
2409  NULL),
2412  struct ZoneToNameMessage,
2413  NULL),
2417  NULL),
2418  GNUNET_MQ_hd_fixed_size (iteration_next,
2420  struct ZoneIterationNextMessage,
2421  NULL),
2422  GNUNET_MQ_hd_fixed_size (iteration_stop,
2424  struct ZoneIterationStopMessage,
2425  NULL),
2426  GNUNET_MQ_hd_fixed_size (monitor_start,
2428  struct ZoneMonitorStartMessage,
2429  NULL),
2430  GNUNET_MQ_hd_fixed_size (monitor_next,
2432  struct ZoneMonitorNextMessage,
2433  NULL),
2435 
2436 
2437 /* 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:77
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:300
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.
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:368
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:1293
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...
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:350
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:197
uint16_t name_len
Length of the name.
Definition: namestore.h:224
#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 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:240
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:164
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:208
uint16_t name_len
Name length.
Definition: namestore.h:268
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:258
common internal definitions for namestore service
Handle to a client that is connected to a service.
Definition: service.c:249
uint16_t rd_count
Number of records contained.
Definition: namestore.h:234
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:288
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:341
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:207
#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:1246
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
#define GNUNET_memcpy(dst, src, n)
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:278
#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:1273
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:316
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:388
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:2704
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:2618
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:355
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.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
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:245
#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:79
#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:241
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.
const char * name
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:273
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:263
#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:311
#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:125
#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:324
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:219
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:214
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:202
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
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:373
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:96
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:229
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:192
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:525
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:80
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:141
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:210
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:258
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:380
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:792
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.
static size_t data_size
Number of bytes in data.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone key.
Definition: namestore.h:360
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:373
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:2533
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:393
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:965
#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...