GNUnet  0.11.x
namestore_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2013, 2016 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 
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_crypto_lib.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_dnsparser_lib.h"
34 #include "gnunet_arm_service.h"
35 #include "gnunet_signatures.h"
36 #include "gnunet_gns_service.h"
38 #include "namestore.h"
39 
40 
41 #define LOG(kind, ...) GNUNET_log_from (kind, "namestore-api", __VA_ARGS__)
42 
47 #define NAMESTORE_DELAY_TOLERANCE GNUNET_TIME_UNIT_MINUTES
48 
54 {
59 
64 
69 
74 
78  void *cont_cls;
79 
84 
88  void *proc_cls;
89 
94 
98  void *error_cb_cls;
99 
105 
110 
114  uint32_t op_id;
115 };
116 
117 
122 {
127 
132 
137 
142 
147 
152 
156  void *proc_cls;
157 
162 
167 
173 
178 
182  uint32_t op_id;
183 };
184 
185 
190 {
195 
200 
205 
210 
215 
220 
225 
229  struct GNUNET_TIME_Relative reconnect_delay;
230 
235 
239  uint32_t last_op_id_used;
240 };
241 
242 
248 static void
250 
251 
259 static struct GNUNET_NAMESTORE_QueueEntry *
260 find_qe (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
261 {
263 
264  for (qe = h->op_head; qe != NULL; qe = qe->next)
265  if (qe->op_id == rid)
266  return qe;
267  return NULL;
268 }
269 
270 
278 static struct GNUNET_NAMESTORE_ZoneIterator *
279 find_zi (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
280 {
282 
283  for (ze = h->z_head; ze != NULL; ze = ze->next)
284  if (ze->op_id == rid)
285  return ze;
286  return NULL;
287 }
288 
289 
295 static void
297 {
298  struct GNUNET_NAMESTORE_Handle *h = qe->h;
299 
301  if (NULL != qe->env)
302  GNUNET_MQ_discard (qe->env);
303  if (NULL != qe->timeout_task)
305  GNUNET_free (qe);
306 }
307 
308 
314 static void
316 {
317  struct GNUNET_NAMESTORE_Handle *h = ze->h;
318 
320  if (NULL != ze->env)
321  GNUNET_MQ_discard (ze->env);
322  GNUNET_free (ze);
323 }
324 
325 
335 static int
336 check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count)
337 {
338  struct GNUNET_GNSRECORD_Data rd[rd_count];
339 
340  if (GNUNET_OK !=
341  GNUNET_GNSRECORD_records_deserialize (rd_len, rd_buf, rd_count, rd))
342  {
343  GNUNET_break (0);
344  return GNUNET_SYSERR;
345  }
346  return GNUNET_OK;
347 }
348 
349 
357 static void
359  const struct RecordStoreResponseMessage *msg)
360 {
361  struct GNUNET_NAMESTORE_Handle *h = cls;
363  int res;
364  const char *emsg;
365 
366  qe = find_qe (h, ntohl (msg->gns_header.r_id));
367  res = ntohl (msg->op_result);
369  "Received RECORD_STORE_RESPONSE with result %d\n",
370  res);
371  /* TODO: add actual error message from namestore to response... */
372  if (GNUNET_SYSERR == res)
373  emsg = _ ("Namestore failed to store record\n");
374  else
375  emsg = NULL;
376  if (NULL != qe->cont)
377  qe->cont (qe->cont_cls, res, emsg);
378  free_qe (qe);
379 }
380 
381 
390 static int
392 {
393  const char *name;
394  size_t exp_msg_len;
395  size_t msg_len;
396  size_t name_len;
397  size_t rd_len;
398 
399  (void) cls;
400  rd_len = ntohs (msg->rd_len);
401  msg_len = ntohs (msg->gns_header.header.size);
402  name_len = ntohs (msg->name_len);
403  exp_msg_len = sizeof(*msg) + name_len + rd_len;
404  if (msg_len != exp_msg_len)
405  {
406  GNUNET_break (0);
407  return GNUNET_SYSERR;
408  }
409  name = (const char *) &msg[1];
410  if ((name_len > 0) && ('\0' != name[name_len - 1]))
411  {
412  GNUNET_break (0);
413  return GNUNET_SYSERR;
414  }
415  if (GNUNET_NO == ntohs (msg->found))
416  {
417  if (0 != ntohs (msg->rd_count))
418  {
419  GNUNET_break (0);
420  return GNUNET_SYSERR;
421  }
422  return GNUNET_OK;
423  }
424  return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
425 }
426 
427 
435 static void
437 {
438  struct GNUNET_NAMESTORE_Handle *h = cls;
440  const char *name;
441  const char *rd_tmp;
442  size_t name_len;
443  size_t rd_len;
444  unsigned int rd_count;
445 
446  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT\n");
447  qe = find_qe (h, ntohl (msg->gns_header.r_id));
448  if (NULL == qe)
449  return;
450  rd_len = ntohs (msg->rd_len);
451  rd_count = ntohs (msg->rd_count);
452  name_len = ntohs (msg->name_len);
453  name = (const char *) &msg[1];
454  if (GNUNET_NO == ntohs (msg->found))
455  {
456  /* label was not in namestore */
457  if (NULL != qe->proc)
458  qe->proc (qe->proc_cls, &msg->private_key, name, 0, NULL);
459  free_qe (qe);
460  return;
461  }
462 
463  rd_tmp = &name[name_len];
464  {
465  struct GNUNET_GNSRECORD_Data rd[rd_count];
466 
467  GNUNET_assert (
468  GNUNET_OK ==
469  GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
470  if (0 == name_len)
471  name = NULL;
472  if (NULL != qe->proc)
473  qe->proc (qe->proc_cls,
474  &msg->private_key,
475  name,
476  rd_count,
477  (rd_count > 0) ? rd : NULL);
478  }
479  free_qe (qe);
480 }
481 
482 
491 static int
492 check_record_result (void *cls, const struct RecordResultMessage *msg)
493 {
494  static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy;
495  const char *name;
496  size_t msg_len;
497  size_t name_len;
498  size_t rd_len;
499 
500  (void) cls;
501  rd_len = ntohs (msg->rd_len);
502  msg_len = ntohs (msg->gns_header.header.size);
503  name_len = ntohs (msg->name_len);
504  if (0 != ntohs (msg->reserved))
505  {
506  GNUNET_break (0);
507  return GNUNET_SYSERR;
508  }
509  if (msg_len != sizeof(struct RecordResultMessage) + name_len + rd_len)
510  {
511  GNUNET_break (0);
512  return GNUNET_SYSERR;
513  }
514  name = (const char *) &msg[1];
515  if ((0 == name_len) || ('\0' != name[name_len - 1]))
516  {
517  GNUNET_break (0);
518  return GNUNET_SYSERR;
519  }
520  if (0 == GNUNET_memcmp (&msg->private_key, &priv_dummy))
521  {
522  GNUNET_break (0);
523  return GNUNET_SYSERR;
524  }
525  return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
526 }
527 
528 
536 static void
537 handle_record_result (void *cls, const struct RecordResultMessage *msg)
538 {
539  struct GNUNET_NAMESTORE_Handle *h = cls;
542  const char *name;
543  const char *rd_tmp;
544  size_t name_len;
545  size_t rd_len;
546  unsigned int rd_count;
547 
548  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT\n");
549  rd_len = ntohs (msg->rd_len);
550  rd_count = ntohs (msg->rd_count);
551  name_len = ntohs (msg->name_len);
552  ze = find_zi (h, ntohl (msg->gns_header.r_id));
553  qe = find_qe (h, ntohl (msg->gns_header.r_id));
554  if ((NULL == ze) && (NULL == qe))
555  return; /* rid not found */
556  if ((NULL != ze) && (NULL != qe))
557  {
558  GNUNET_break (0); /* rid ambigous */
559  force_reconnect (h);
560  return;
561  }
562  name = (const char *) &msg[1];
563  rd_tmp = &name[name_len];
564  {
565  struct GNUNET_GNSRECORD_Data rd[rd_count];
566 
567  GNUNET_assert (
568  GNUNET_OK ==
569  GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
570  if (0 == name_len)
571  name = NULL;
572  if (NULL != qe)
573  {
574  if (NULL != qe->proc)
575  qe->proc (qe->proc_cls,
576  &msg->private_key,
577  name,
578  rd_count,
579  (rd_count > 0) ? rd : NULL);
580  free_qe (qe);
581  return;
582  }
583  if (NULL != ze)
584  {
585  if (NULL != ze->proc)
586  ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd);
587  return;
588  }
589  }
590  GNUNET_assert (0);
591 }
592 
593 
601 static void
603 {
604  struct GNUNET_NAMESTORE_Handle *h = cls;
607 
608  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT_END\n");
609  ze = find_zi (h, ntohl (msg->r_id));
610  qe = find_qe (h, ntohl (msg->r_id));
611  if ((NULL == ze) && (NULL == qe))
612  return; /* rid not found */
613  if ((NULL != ze) && (NULL != qe))
614  {
615  GNUNET_break (0); /* rid ambigous */
616  force_reconnect (h);
617  return;
618  }
619  LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration completed!\n");
620  if (NULL == ze)
621  {
622  GNUNET_break (0);
623  force_reconnect (h);
624  return;
625  }
626  if (NULL != ze->finish_cb)
627  ze->finish_cb (ze->finish_cb_cls);
628  free_ze (ze);
629 }
630 
631 
640 static int
642  const struct ZoneToNameResponseMessage *msg)
643 {
644  size_t name_len;
645  size_t rd_ser_len;
646  const char *name_tmp;
647 
648  (void) cls;
649  if (GNUNET_OK != ntohs (msg->res))
650  return GNUNET_OK;
651  name_len = ntohs (msg->name_len);
652  rd_ser_len = ntohs (msg->rd_len);
653  if (ntohs (msg->gns_header.header.size) !=
654  sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len)
655  {
656  GNUNET_break (0);
657  return GNUNET_SYSERR;
658  }
659  name_tmp = (const char *) &msg[1];
660  if ((name_len > 0) && ('\0' != name_tmp[name_len - 1]))
661  {
662  GNUNET_break (0);
663  return GNUNET_SYSERR;
664  }
665  return check_rd (rd_ser_len, &name_tmp[name_len], ntohs (msg->rd_count));
666 }
667 
668 
676 static void
678  const struct ZoneToNameResponseMessage *msg)
679 {
680  struct GNUNET_NAMESTORE_Handle *h = cls;
682  int res;
683  size_t name_len;
684  size_t rd_ser_len;
685  unsigned int rd_count;
686  const char *name_tmp;
687  const char *rd_tmp;
688 
689  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME_RESPONSE\n");
690  qe = find_qe (h, ntohl (msg->gns_header.r_id));
691  res = ntohs (msg->res);
692  switch (res)
693  {
694  case GNUNET_SYSERR:
696  "An error occurred during zone to name operation\n");
697  break;
698 
699  case GNUNET_NO:
701  "Namestore has no result for zone to name mapping \n");
702  if (NULL != qe->proc)
703  qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
704  free_qe (qe);
705  return;
706 
707  case GNUNET_YES:
709  "Namestore has result for zone to name mapping \n");
710  name_len = ntohs (msg->name_len);
711  rd_count = ntohs (msg->rd_count);
712  rd_ser_len = ntohs (msg->rd_len);
713  name_tmp = (const char *) &msg[1];
714  rd_tmp = &name_tmp[name_len];
715  {
716  struct GNUNET_GNSRECORD_Data rd[rd_count];
717 
720  rd_tmp,
721  rd_count,
722  rd));
723  /* normal end, call continuation with result */
724  if (NULL != qe->proc)
725  qe->proc (qe->proc_cls, &msg->zone, name_tmp, rd_count, rd);
726  /* return is important here: break would call continuation with error! */
727  free_qe (qe);
728  return;
729  }
730 
731  default:
732  GNUNET_break (0);
733  force_reconnect (h);
734  return;
735  }
736  /* error case, call continuation with error */
737  if (NULL != qe->error_cb)
738  qe->error_cb (qe->error_cb_cls);
739  free_qe (qe);
740 }
741 
742 
751 static void
752 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
753 {
754  struct GNUNET_NAMESTORE_Handle *h = cls;
755 
756  (void) error;
757  force_reconnect (h);
758 }
759 
760 
766 static void
768 {
769  struct GNUNET_MQ_MessageHandler handlers[] =
770  { GNUNET_MQ_hd_fixed_size (record_store_response,
773  h),
774  GNUNET_MQ_hd_var_size (zone_to_name_response,
777  h),
778  GNUNET_MQ_hd_var_size (record_result,
780  struct RecordResultMessage,
781  h),
782  GNUNET_MQ_hd_fixed_size (record_result_end,
785  h),
786  GNUNET_MQ_hd_var_size (lookup_result,
789  h),
793 
794  GNUNET_assert (NULL == h->mq);
795  h->mq =
796  GNUNET_CLIENT_connect (h->cfg, "namestore", handlers, &mq_error_handler, h);
797  if (NULL == h->mq)
798  return;
799  /* re-transmit pending requests that waited for a reconnect... */
800  for (it = h->z_head; NULL != it; it = it->next)
801  {
802  GNUNET_MQ_send (h->mq, it->env);
803  it->env = NULL;
804  }
805  for (qe = h->op_head; NULL != qe; qe = qe->next)
806  {
807  GNUNET_MQ_send (h->mq, qe->env);
808  qe->env = NULL;
809  }
810 }
811 
812 
818 static void
819 reconnect_task (void *cls)
820 {
821  struct GNUNET_NAMESTORE_Handle *h = cls;
822 
823  h->reconnect_task = NULL;
824  reconnect (h);
825 }
826 
827 
833 static void
835 {
838 
839  GNUNET_MQ_destroy (h->mq);
840  h->mq = NULL;
841  while (NULL != (ze = h->z_head))
842  {
843  if (NULL != ze->error_cb)
844  ze->error_cb (ze->error_cb_cls);
845  free_ze (ze);
846  }
847  while (NULL != (qe = h->op_head))
848  {
849  if (NULL != qe->error_cb)
850  qe->error_cb (qe->error_cb_cls);
851  if (NULL != qe->cont)
852  qe->cont (qe->cont_cls,
854  "failure in communication with namestore service");
855  free_qe (qe);
856  }
857 
858  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to namestore\n");
860  h->reconnect_task =
862 }
863 
864 
871 static uint32_t
873 {
874  return h->last_op_id_used++;
875 }
876 
877 
886 {
887  struct GNUNET_NAMESTORE_Handle *h;
888 
889  h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
890  h->cfg = cfg;
891  reconnect (h);
892  if (NULL == h->mq)
893  {
894  GNUNET_free (h);
895  return NULL;
896  }
897  return h;
898 }
899 
900 
907 void
909 {
912 
913  LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
914  GNUNET_break (NULL == h->op_head);
915  while (NULL != (q = h->op_head))
916  {
918  GNUNET_free (q);
919  }
920  GNUNET_break (NULL == h->z_head);
921  while (NULL != (z = h->z_head))
922  {
924  GNUNET_free (z);
925  }
926  if (NULL != h->mq)
927  {
928  GNUNET_MQ_destroy (h->mq);
929  h->mq = NULL;
930  }
931  if (NULL != h->reconnect_task)
932  {
934  h->reconnect_task = NULL;
935  }
936  GNUNET_free (h);
937 }
938 
939 
946 static void
947 warn_delay (void *cls)
948 {
949  struct GNUNET_NAMESTORE_QueueEntry *qe = cls;
950 
951  qe->timeout_task = NULL;
953  "Did not receive response from namestore after %s!\n",
955  GNUNET_YES));
956  if (NULL != qe->cont)
957  {
958  qe->cont (qe->cont_cls, GNUNET_SYSERR, "timeout");
959  qe->cont = NULL;
960  }
962 }
963 
964 
981  struct GNUNET_NAMESTORE_Handle *h,
982  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
983  const char *label,
984  unsigned int rd_count,
985  const struct GNUNET_GNSRECORD_Data *rd,
987  void *cont_cls)
988 {
990  struct GNUNET_MQ_Envelope *env;
991  char *name_tmp;
992  char *rd_ser;
993  ssize_t rd_ser_len;
994  size_t name_len;
995  uint32_t rid;
996  struct RecordStoreMessage *msg;
997  ssize_t sret;
998 
999  name_len = strlen (label) + 1;
1000  if (name_len > MAX_NAME_LEN)
1001  {
1002  GNUNET_break (0);
1003  return NULL;
1004  }
1005  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1006  if (rd_ser_len < 0)
1007  {
1008  GNUNET_break (0);
1009  return NULL;
1010  }
1011  if (rd_ser_len > UINT16_MAX)
1012  {
1013  GNUNET_break (0);
1014  return NULL;
1015  }
1016  rid = get_op_id (h);
1018  qe->h = h;
1019  qe->cont = cont;
1020  qe->cont_cls = cont_cls;
1021  qe->op_id = rid;
1023 
1024  /* setup msg */
1025  env = GNUNET_MQ_msg_extra (msg,
1026  name_len + rd_ser_len,
1028  msg->gns_header.r_id = htonl (rid);
1029  msg->name_len = htons (name_len);
1030  msg->rd_count = htons (rd_count);
1031  msg->rd_len = htons (rd_ser_len);
1032  msg->reserved = htons (0);
1033  msg->private_key = *pkey;
1034 
1035  name_tmp = (char *) &msg[1];
1036  GNUNET_memcpy (name_tmp, label, name_len);
1037  rd_ser = &name_tmp[name_len];
1038  sret = GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1039  if ((0 > sret) || (sret != rd_ser_len))
1040  {
1041  GNUNET_break (0);
1042  GNUNET_free (env);
1043  return NULL;
1044  }
1045  GNUNET_assert (rd_ser_len == sret);
1047  "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n",
1048  label,
1049  rd_count);
1050  qe->timeout_task =
1052  if (NULL == h->mq)
1053  {
1054  qe->env = env;
1056  "Delaying NAMESTORE_RECORD_STORE message as namestore is not ready!\n");
1057  }
1058  else
1059  {
1060  GNUNET_MQ_send (h->mq, env);
1061  }
1062  return qe;
1063 }
1064 
1065 
1078  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1079  const char *nick,
1081  void *cont_cls)
1082 {
1083  struct GNUNET_GNSRECORD_Data rd;
1084 
1085  if (NULL == h->mq)
1086  return NULL;
1087  memset (&rd, 0, sizeof(rd));
1088  rd.data = nick;
1089  rd.data_size = strlen (nick) + 1;
1094  pkey,
1096  1,
1097  &rd,
1098  cont,
1099  cont_cls);
1100 }
1101 
1102 
1117  struct GNUNET_NAMESTORE_Handle *h,
1118  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1119  const char *label,
1121  void *error_cb_cls,
1123  void *rm_cls)
1124 {
1126  struct GNUNET_MQ_Envelope *env;
1127  struct LabelLookupMessage *msg;
1128  size_t label_len;
1129 
1130  if (1 == (label_len = strlen (label) + 1))
1131  {
1132  GNUNET_break (0);
1133  return NULL;
1134  }
1135 
1137  qe->h = h;
1138  qe->error_cb = error_cb;
1139  qe->error_cb_cls = error_cb_cls;
1140  qe->proc = rm;
1141  qe->proc_cls = rm_cls;
1142  qe->op_id = get_op_id (h);
1144 
1145  env = GNUNET_MQ_msg_extra (msg,
1146  label_len,
1148  msg->gns_header.r_id = htonl (qe->op_id);
1149  msg->zone = *pkey;
1150  msg->label_len = htonl (label_len);
1151  GNUNET_memcpy (&msg[1], label, label_len);
1152  if (NULL == h->mq)
1153  qe->env = env;
1154  else
1155  GNUNET_MQ_send (h->mq, env);
1156  return qe;
1157 }
1158 
1159 
1177  struct GNUNET_NAMESTORE_Handle *h,
1178  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1179  const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
1181  void *error_cb_cls,
1183  void *proc_cls)
1184 {
1186  struct GNUNET_MQ_Envelope *env;
1187  struct ZoneToNameMessage *msg;
1188  uint32_t rid;
1189 
1190  rid = get_op_id (h);
1192  qe->h = h;
1193  qe->error_cb = error_cb;
1194  qe->error_cb_cls = error_cb_cls;
1195  qe->proc = proc;
1196  qe->proc_cls = proc_cls;
1197  qe->op_id = rid;
1199 
1201  msg->gns_header.r_id = htonl (rid);
1202  msg->zone = *zone;
1203  msg->value_zone = *value_zone;
1204  if (NULL == h->mq)
1205  qe->env = env;
1206  else
1207  GNUNET_MQ_send (h->mq, env);
1208  return qe;
1209 }
1210 
1211 
1233  struct GNUNET_NAMESTORE_Handle *h,
1234  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1236  void *error_cb_cls,
1238  void *proc_cls,
1240  void *finish_cb_cls)
1241 {
1242  struct GNUNET_NAMESTORE_ZoneIterator *it;
1243  struct GNUNET_MQ_Envelope *env;
1245  uint32_t rid;
1246 
1247  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1248  rid = get_op_id (h);
1250  it->h = h;
1251  it->error_cb = error_cb;
1252  it->error_cb_cls = error_cb_cls;
1253  it->finish_cb = finish_cb;
1254  it->finish_cb_cls = finish_cb_cls;
1255  it->proc = proc;
1256  it->proc_cls = proc_cls;
1257  it->op_id = rid;
1258  if (NULL != zone)
1259  it->zone = *zone;
1262  msg->gns_header.r_id = htonl (rid);
1263  if (NULL != zone)
1264  msg->zone = *zone;
1265  if (NULL == h->mq)
1266  it->env = env;
1267  else
1268  GNUNET_MQ_send (h->mq, env);
1269  return it;
1270 }
1271 
1272 
1281 void
1283  uint64_t limit)
1284 {
1285  struct GNUNET_NAMESTORE_Handle *h = it->h;
1286  struct ZoneIterationNextMessage *msg;
1287  struct GNUNET_MQ_Envelope *env;
1288 
1290  "Sending ZONE_ITERATION_NEXT message with limit %llu\n",
1291  (unsigned long long) limit);
1293  msg->gns_header.r_id = htonl (it->op_id);
1294  msg->limit = GNUNET_htonll (limit);
1295  GNUNET_MQ_send (h->mq, env);
1296 }
1297 
1298 
1304 void
1306 {
1307  struct GNUNET_NAMESTORE_Handle *h = it->h;
1308  struct GNUNET_MQ_Envelope *env;
1309  struct ZoneIterationStopMessage *msg;
1310 
1311  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_STOP message\n");
1312  if (NULL != h->mq)
1313  {
1314  env =
1316  msg->gns_header.r_id = htonl (it->op_id);
1317  GNUNET_MQ_send (h->mq, env);
1318  }
1319  free_ze (it);
1320 }
1321 
1322 
1329 void
1331 {
1332  free_qe (qe);
1333 }
1334 
1335 
1336 /* end of namestore_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_NAMESTORE_Handle * h
Main handle to access the namestore.
Definition: namestore_api.c:68
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
static struct GNUNET_DATASTORE_QueueEntry * qe
Current operation.
GNUNET_SCHEDULER_TaskCallback error_cb
Function to call on errors.
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.
struct GNUNET_MQ_Envelope * env
Envelope of the message to send to the service, if not yet sent.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
void(* GNUNET_NAMESTORE_ContinuationWithStatus)(void *cls, int32_t success, const char *emsg)
Continuation called to notify client about result of the operation.
uint32_t label_len
Length of the name.
Definition: namestore.h:132
static char * pkey
Public key of the zone to look in, in ASCII.
static void handle_lookup_result(void *cls, const struct LabelLookupResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
GNUNET_SCHEDULER_TaskCallback finish_cb
Function to call on completion.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
static int check_zone_to_name_response(void *cls, const struct ZoneToNameResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
GNUNET_NAMESTORE_RecordMonitor proc
Function to call with the records we get back; or NULL.
Definition: namestore_api.c:83
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:362
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:163
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls)
Lookup an item in the namestore.
GNUNET_MQ_Error
Error codes for the queue.
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_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT)...
GNUNET_NAMESTORE_RecordMonitor proc
The continuation to call with the results.
uint16_t reserved
always zero (for alignment)
Definition: namestore.h:281
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.
GNUNET_SCHEDULER_TaskCallback error_cb
Function to call on errors.
Definition: namestore_api.c:93
struct GNUNET_NAMESTORE_QueueEntry * prev
Kept in a DLL.
Definition: namestore_api.c:63
uint32_t op_id
The operation id this zone iteration operation has.
Start a zone iteration for the given zone.
Definition: namestore.h:345
void * proc_cls
Closure for proc.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:196
uint16_t name_len
Length of the name.
Definition: namestore.h:223
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void(* GNUNET_NAMESTORE_RecordMonitor)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
static void handle_record_store_response(void *cls, const struct RecordStoreResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
int16_t res
result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error ...
Definition: namestore.h:239
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
size_t data_size
Number of bytes in data.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record...
static void handle_record_result_end(void *cls, const struct GNUNET_NAMESTORE_Header *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END.
Private ECC key encoded for transmission.
#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.
void * error_cb_cls
Closure for error_cb.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP
Client to service: lookup label.
void * proc_cls
Closure for proc.
Definition: namestore_api.c:88
void * error_cb_cls
Closure for error_cb.
Definition: namestore_api.c:98
#define GNUNET_GNSRECORD_TYPE_NICK
Record type for GNS nick names ("NICK").
#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...
uint32_t last_op_id_used
The last operation id used for a NAMESTORE operation.
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
static int check_record_result(void *cls, const struct RecordResultMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static void free_ze(struct GNUNET_NAMESTORE_ZoneIterator *ze)
Free ze.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namestore.
uint16_t name_len
Name length.
Definition: namestore.h:266
common internal definitions for namestore service
static char * zone
Name of the zone we manage.
uint16_t rd_count
Number of records contained.
Definition: namestore.h:233
int32_t op_result
GNUNET_SYSERR on failure, GNUNET_OK on success
Definition: namestore.h:115
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size ...
Definition: namestore.h:46
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:286
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
cryptographic primitives for GNUnet
struct GNUNET_CRYPTO_EcdsaPublicKey value_zone
The public key of the target zone.
Definition: namestore.h:206
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Handle for a zone iterator operation.
struct GNUNET_NAMESTORE_QueueEntry * next
Kept in a DLL.
Definition: namestore_api.c:58
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
struct GNUNET_TIME_Relative reconnect_delay
Delay introduced before we reconnect.
static int check_rd(size_t rd_len, const void *rd_buf, unsigned int rd_count)
Check that rd_buf of lenght rd_len contains rd_count records.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:78
const void * data
Binary value stored in the DNS record.
uint16_t rd_count
Number of records contained.
Definition: namestore.h:276
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
Client to service: store records (as authority)
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void handle_record_result(void *cls, const struct RecordResultMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Connection to the NAMESTORE service.
struct GNUNET_MQ_Handle * mq
Connection to the service (if available).
uint64_t expiration_time
Expiration time for the DNS record.
static void force_reconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from service and then reconnect.
static struct GNUNET_NAMESTORE_ZoneIterator * find_zi(struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
Find the zone iteration entry that matches the rid.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:687
#define NAMESTORE_DELAY_TOLERANCE
We grant the namestore up to 1 minute of latency, if it is slower than that, store queries will fail...
Definition: namestore_api.c:47
Stop zone iteration for the given operation.
Definition: namestore.h:381
uint16_t name_len
Name length.
Definition: namestore.h:73
struct GNUNET_MQ_Envelope * env
Envelope of the message to send to the service, if not yet sent.
uint16_t name_len
Name length.
Definition: namestore.h:158
This is a private record of this peer and it should thus not be handed out to other peers...
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:350
Message handler for a specific message type.
static int res
static void warn_delay(void *cls)
Task launched to warn the user that the namestore is excessively slow and that a query was thus dropp...
uint16_t rd_count
Number of records contained.
Definition: namestore.h:83
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
Client to service: "reverse" lookup for zone name based on zone key.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
struct GNUNET_NAMESTORE_QueueEntry * op_tail
Tail of pending namestore queue entries.
struct GNUNET_NAMESTORE_ZoneIterator * next
Kept in a DLL.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone that contained the name.
Definition: namestore.h:244
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
An QueueEntry used to store information for a pending NAMESTORE record operation. ...
Definition: namestore_api.c:53
struct GNUNET_NAMESTORE_Handle * h
Main handle to access the namestore.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the NAMESTORE service.
struct GNUNET_NAMESTORE_ZoneIterator * prev
Kept in a DLL.
uint32_t op_id
The operation id this zone iteration operation has.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
uint16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:174
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:271
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
GNUNET_NAMESTORE_ContinuationWithStatus cont
Continuation to call.
Definition: namestore_api.c:73
static void reconnect(struct GNUNET_NAMESTORE_Handle *h)
Reconnect to namestore service.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:261
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
static void free_qe(struct GNUNET_NAMESTORE_QueueEntry *qe)
Free qe.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
int reconnect
Should we reconnect to service due to some serious error?
#define LOG(kind,...)
Definition: namestore_api.c:41
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:218
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:93
void * finish_cb_cls
Closure for error_cb.
Store a record to the namestore (as authority).
Definition: namestore.h:58
Respone for zone to name lookup.
Definition: namestore.h:213
void * cont_cls
Closure for cont.
Definition: namestore_api.c:78
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:201
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.
configuration data
Definition: configuration.c:85
const char * name
Response to a record storage request.
Definition: namestore.h:105
struct GNUNET_NAMESTORE_QueueEntry * op_head
Head of pending namestore queue entries.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct GNUNET_NAMESTORE_ZoneIterator * z_head
Head of pending namestore zone iterator entries.
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
static uint32_t get_op_id(struct GNUNET_NAMESTORE_Handle *h)
Get a fresh operation id to distinguish between namestore requests.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
Look for an existing PKEY delegation record for a given public key.
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:179
Entry in list of pending tasks.
Definition: scheduler.c:134
Generic namestore message with op id.
Definition: namestore.h:40
static void handle_zone_to_name_response(void *cls, const struct ZoneToNameResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
struct GNUNET_SCHEDULER_Task * timeout_task
Task scheduled to warn us if the namestore is way too slow.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:228
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:127
Lookup a name for a zone hash.
Definition: namestore.h:191
Lookup a label.
Definition: namestore.h:122
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:77
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.
struct GNUNET_NAMESTORE_ZoneIterator * z_tail
Tail of pending namestore zone iterator entries.
Record is returned from the namestore (as authority).
Definition: namestore.h:256
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:374
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
static struct GNUNET_NAMESTORE_QueueEntry * find_qe(struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
Find the queue entry that matches the rid.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_set_nick(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const char *nick, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Set the desired nick name for a zone.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone key.
Definition: namestore.h:355
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:367
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:386
Lookup a label.
Definition: namestore.h:148
static int check_lookup_result(void *cls, const struct LabelLookupResponseMessage *msg)
Check validity of an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:137
static void reconnect_task(void *cls)
Re-establish the connection to the service.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Private key of the zone.