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 
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 
300  GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
301  if (NULL != qe->env)
303  if (NULL != qe->timeout_task)
304  GNUNET_SCHEDULER_cancel (qe->timeout_task);
305  GNUNET_free (qe);
306 }
307 
308 
314 static void
316 {
317  struct GNUNET_NAMESTORE_Handle *h = ze->h;
318 
319  GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, ze);
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 
357 static int
359  const struct RecordStoreResponseMessage *msg)
360 {
361  const char *emsg;
362  size_t msg_len;
363  size_t emsg_len;
364 
365  (void) cls;
366  msg_len = ntohs (msg->gns_header.header.size);
367  emsg_len = ntohs (msg->emsg_len);
368  if (0 != ntohs (msg->reserved))
369  {
370  GNUNET_break (0);
371  return GNUNET_SYSERR;
372  }
373  if (msg_len != sizeof(struct RecordStoreResponseMessage) + emsg_len)
374  {
375  GNUNET_break (0);
376  return GNUNET_SYSERR;
377  }
378  emsg = (const char *) &msg[1];
379  if ((0 != emsg_len) && ('\0' != emsg[emsg_len - 1]))
380  {
381  GNUNET_break (0);
382  return GNUNET_SYSERR;
383  }
384  return GNUNET_OK;
385 }
386 
387 
395 static void
397  const struct RecordStoreResponseMessage *msg)
398 {
399  struct GNUNET_NAMESTORE_Handle *h = cls;
401  int res;
402  const char *emsg;
403 
404  qe = find_qe (h, ntohl (msg->gns_header.r_id));
405  emsg = (const char *) &msg[1];
406  res = ntohl (msg->op_result);
408  "Received RECORD_STORE_RESPONSE with result %d\n",
409  res);
410  if (NULL == qe)
411  return;
412  if (NULL != qe->cont)
413  qe->cont (qe->cont_cls, res,
414  (GNUNET_OK == res) ? NULL : emsg);
415  free_qe (qe);
416 }
417 
418 
427 static int
429 {
430  const char *name;
431  size_t exp_msg_len;
432  size_t msg_len;
433  size_t name_len;
434  size_t rd_len;
435 
436  (void) cls;
437  rd_len = ntohs (msg->rd_len);
438  msg_len = ntohs (msg->gns_header.header.size);
439  name_len = ntohs (msg->name_len);
440  exp_msg_len = sizeof(*msg) + name_len + rd_len;
441  if (msg_len != exp_msg_len)
442  {
443  GNUNET_break (0);
444  return GNUNET_SYSERR;
445  }
446  name = (const char *) &msg[1];
447  if ((name_len > 0) && ('\0' != name[name_len - 1]))
448  {
449  GNUNET_break (0);
450  return GNUNET_SYSERR;
451  }
452  if (GNUNET_NO == ntohs (msg->found))
453  {
454  if (0 != ntohs (msg->rd_count))
455  {
456  GNUNET_break (0);
457  return GNUNET_SYSERR;
458  }
459  return GNUNET_OK;
460  }
461  return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
462 }
463 
464 
472 static void
474 {
475  struct GNUNET_NAMESTORE_Handle *h = cls;
477  const char *name;
478  const char *rd_tmp;
479  size_t name_len;
480  size_t rd_len;
481  unsigned int rd_count;
482  int16_t found = (int16_t) ntohs (msg->found);
483 
484  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n",
485  found);
486  qe = find_qe (h, ntohl (msg->gns_header.r_id));
487  if (NULL == qe)
488  return;
489  rd_len = ntohs (msg->rd_len);
490  rd_count = ntohs (msg->rd_count);
491  name_len = ntohs (msg->name_len);
492  name = (const char *) &msg[1];
493  if (GNUNET_NO == found)
494  {
495  /* label was not in namestore */
496  if (NULL != qe->proc)
497  qe->proc (qe->proc_cls, &msg->private_key, name, 0, NULL);
498  free_qe (qe);
499  return;
500  }
501  if (GNUNET_SYSERR == found)
502  {
503  if (NULL != qe->error_cb)
504  qe->error_cb (qe->error_cb_cls);
505  free_qe (qe);
506  return;
507  }
508 
509  rd_tmp = &name[name_len];
510  {
511  struct GNUNET_GNSRECORD_Data rd[rd_count];
512 
513  GNUNET_assert (
514  GNUNET_OK ==
515  GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
516  if (0 == name_len)
517  name = NULL;
518  if (NULL != qe->proc)
519  qe->proc (qe->proc_cls,
520  &msg->private_key,
521  name,
522  rd_count,
523  (rd_count > 0) ? rd : NULL);
524  }
525  free_qe (qe);
526 }
527 
528 
537 static int
538 check_record_result (void *cls, const struct RecordResultMessage *msg)
539 {
540  static struct GNUNET_IDENTITY_PrivateKey priv_dummy;
541  const char *name;
542  size_t msg_len;
543  size_t name_len;
544  size_t rd_len;
545 
546  (void) cls;
547  rd_len = ntohs (msg->rd_len);
548  msg_len = ntohs (msg->gns_header.header.size);
549  name_len = ntohs (msg->name_len);
550  if (0 != ntohs (msg->reserved))
551  {
552  GNUNET_break (0);
553  return GNUNET_SYSERR;
554  }
555  if (msg_len != sizeof(struct RecordResultMessage) + name_len + rd_len)
556  {
557  GNUNET_break (0);
558  return GNUNET_SYSERR;
559  }
560  name = (const char *) &msg[1];
561  if ((0 == name_len) || ('\0' != name[name_len - 1]))
562  {
563  GNUNET_break (0);
564  return GNUNET_SYSERR;
565  }
566  if (0 == GNUNET_memcmp (&msg->private_key, &priv_dummy))
567  {
568  GNUNET_break (0);
569  return GNUNET_SYSERR;
570  }
571  return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
572 }
573 
574 
582 static void
583 handle_record_result (void *cls, const struct RecordResultMessage *msg)
584 {
585  struct GNUNET_NAMESTORE_Handle *h = cls;
588  const char *name;
589  const char *rd_tmp;
590  size_t name_len;
591  size_t rd_len;
592  unsigned int rd_count;
593 
594  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT\n");
595  rd_len = ntohs (msg->rd_len);
596  rd_count = ntohs (msg->rd_count);
597  name_len = ntohs (msg->name_len);
598  ze = find_zi (h, ntohl (msg->gns_header.r_id));
599  qe = find_qe (h, ntohl (msg->gns_header.r_id));
600  if ((NULL == ze) && (NULL == qe))
601  return; /* rid not found */
602  if ((NULL != ze) && (NULL != qe))
603  {
604  GNUNET_break (0); /* rid ambiguous */
605  force_reconnect (h);
606  return;
607  }
608  name = (const char *) &msg[1];
609  rd_tmp = &name[name_len];
610  {
611  struct GNUNET_GNSRECORD_Data rd[rd_count];
612 
613  GNUNET_assert (
614  GNUNET_OK ==
615  GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
616  if (0 == name_len)
617  name = NULL;
618  if (NULL != qe)
619  {
620  if (NULL != qe->proc)
621  qe->proc (qe->proc_cls,
622  &msg->private_key,
623  name,
624  rd_count,
625  (rd_count > 0) ? rd : NULL);
626  free_qe (qe);
627  return;
628  }
629  if (NULL != ze)
630  {
631  if (NULL != ze->proc)
632  ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd);
633  return;
634  }
635  }
636  GNUNET_assert (0);
637 }
638 
639 
647 static void
649 {
650  struct GNUNET_NAMESTORE_Handle *h = cls;
653 
654  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT_END\n");
655  ze = find_zi (h, ntohl (msg->r_id));
656  qe = find_qe (h, ntohl (msg->r_id));
657  if ((NULL == ze) && (NULL == qe))
658  return; /* rid not found */
659  if ((NULL != ze) && (NULL != qe))
660  {
661  GNUNET_break (0); /* rid ambiguous */
662  force_reconnect (h);
663  return;
664  }
665  LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration completed!\n");
666  if (NULL == ze)
667  {
668  GNUNET_break (0);
669  force_reconnect (h);
670  return;
671  }
672  if (NULL != ze->finish_cb)
673  ze->finish_cb (ze->finish_cb_cls);
674  free_ze (ze);
675 }
676 
677 
686 static int
688  const struct ZoneToNameResponseMessage *msg)
689 {
690  size_t name_len;
691  size_t rd_ser_len;
692  const char *name_tmp;
693 
694  (void) cls;
695  if (GNUNET_OK != ntohs (msg->res))
696  return GNUNET_OK;
697  name_len = ntohs (msg->name_len);
698  rd_ser_len = ntohs (msg->rd_len);
699  if (ntohs (msg->gns_header.header.size) !=
700  sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len)
701  {
702  GNUNET_break (0);
703  return GNUNET_SYSERR;
704  }
705  name_tmp = (const char *) &msg[1];
706  if ((name_len > 0) && ('\0' != name_tmp[name_len - 1]))
707  {
708  GNUNET_break (0);
709  return GNUNET_SYSERR;
710  }
711  return check_rd (rd_ser_len, &name_tmp[name_len], ntohs (msg->rd_count));
712 }
713 
714 
722 static void
724  const struct ZoneToNameResponseMessage *msg)
725 {
726  struct GNUNET_NAMESTORE_Handle *h = cls;
728  int res;
729  size_t name_len;
730  size_t rd_ser_len;
731  unsigned int rd_count;
732  const char *name_tmp;
733  const char *rd_tmp;
734 
735  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME_RESPONSE\n");
736  qe = find_qe (h, ntohl (msg->gns_header.r_id));
737  if (NULL == qe)
738  {
740  "Response queue already gone...\n");
741  return;
742  }
743  res = ntohs (msg->res);
744  switch (res)
745  {
746  case GNUNET_SYSERR:
748  "An error occurred during zone to name operation\n");
749  break;
750 
751  case GNUNET_NO:
753  "Namestore has no result for zone to name mapping \n");
754  if (NULL != qe->proc)
755  qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
756  free_qe (qe);
757  return;
758 
759  case GNUNET_YES:
761  "Namestore has result for zone to name mapping \n");
762  name_len = ntohs (msg->name_len);
763  rd_count = ntohs (msg->rd_count);
764  rd_ser_len = ntohs (msg->rd_len);
765  name_tmp = (const char *) &msg[1];
766  rd_tmp = &name_tmp[name_len];
767  {
768  struct GNUNET_GNSRECORD_Data rd[rd_count];
769 
772  rd_tmp,
773  rd_count,
774  rd));
775  /* normal end, call continuation with result */
776  if (NULL != qe->proc)
777  qe->proc (qe->proc_cls, &msg->zone, name_tmp, rd_count, rd);
778  /* return is important here: break would call continuation with error! */
779  free_qe (qe);
780  return;
781  }
782 
783  default:
784  GNUNET_break (0);
785  force_reconnect (h);
786  return;
787  }
788  /* error case, call continuation with error */
789  if (NULL != qe->error_cb)
790  qe->error_cb (qe->error_cb_cls);
791  free_qe (qe);
792 }
793 
794 
803 static void
804 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
805 {
806  struct GNUNET_NAMESTORE_Handle *h = cls;
807 
808  (void) error;
809  force_reconnect (h);
810 }
811 
812 
818 static void
820 {
822  { GNUNET_MQ_hd_var_size (record_store_response,
825  h),
826  GNUNET_MQ_hd_var_size (zone_to_name_response,
829  h),
830  GNUNET_MQ_hd_var_size (record_result,
832  struct RecordResultMessage,
833  h),
834  GNUNET_MQ_hd_fixed_size (record_result_end,
837  h),
838  GNUNET_MQ_hd_var_size (lookup_result,
841  h),
845 
846  GNUNET_assert (NULL == h->mq);
847  h->mq =
849  if (NULL == h->mq)
850  return;
851  /* re-transmit pending requests that waited for a reconnect... */
852  for (it = h->z_head; NULL != it; it = it->next)
853  {
854  GNUNET_MQ_send (h->mq, it->env);
855  it->env = NULL;
856  }
857  for (qe = h->op_head; NULL != qe; qe = qe->next)
858  {
859  GNUNET_MQ_send (h->mq, qe->env);
860  qe->env = NULL;
861  }
862 }
863 
864 
870 static void
871 reconnect_task (void *cls)
872 {
873  struct GNUNET_NAMESTORE_Handle *h = cls;
874 
875  h->reconnect_task = NULL;
876  reconnect (h);
877 }
878 
879 
885 static void
887 {
890 
892  h->mq = NULL;
893  while (NULL != (ze = h->z_head))
894  {
895  if (NULL != ze->error_cb)
896  ze->error_cb (ze->error_cb_cls);
897  free_ze (ze);
898  }
899  while (NULL != (qe = h->op_head))
900  {
901  if (NULL != qe->error_cb)
902  qe->error_cb (qe->error_cb_cls);
903  if (NULL != qe->cont)
904  qe->cont (qe->cont_cls,
906  "failure in communication with namestore service");
907  free_qe (qe);
908  }
909 
910  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to namestore\n");
911  h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
912  h->reconnect_task =
913  GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect_task, h);
914 }
915 
916 
923 static uint32_t
925 {
926  return h->last_op_id_used++;
927 }
928 
929 
938 {
939  struct GNUNET_NAMESTORE_Handle *h;
940 
942  h->cfg = cfg;
943  reconnect (h);
944  if (NULL == h->mq)
945  {
946  GNUNET_free (h);
947  return NULL;
948  }
949  return h;
950 }
951 
952 
959 void
961 {
964 
965  LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
966  GNUNET_break (NULL == h->op_head);
967  while (NULL != (q = h->op_head))
968  {
969  GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q);
970  GNUNET_free (q);
971  }
972  GNUNET_break (NULL == h->z_head);
973  while (NULL != (z = h->z_head))
974  {
975  GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z);
976  GNUNET_free (z);
977  }
978  if (NULL != h->mq)
979  {
981  h->mq = NULL;
982  }
983  if (NULL != h->reconnect_task)
984  {
986  h->reconnect_task = NULL;
987  }
988  GNUNET_free (h);
989 }
990 
991 
998 static void
999 warn_delay (void *cls)
1000 {
1001  struct GNUNET_NAMESTORE_QueueEntry *qe = cls;
1002 
1003  qe->timeout_task = NULL;
1005  "Did not receive response from namestore after %s!\n",
1007  GNUNET_YES));
1008  if (NULL != qe->cont)
1009  {
1010  qe->cont (qe->cont_cls, GNUNET_SYSERR, "timeout");
1011  qe->cont = NULL;
1012  }
1014 }
1015 
1016 
1019  struct GNUNET_NAMESTORE_Handle *h,
1020  const struct GNUNET_IDENTITY_PrivateKey *pkey,
1021  const char *label,
1022  unsigned int rd_count,
1023  const struct GNUNET_GNSRECORD_Data *rd,
1025  void *cont_cls)
1026 {
1028  struct GNUNET_MQ_Envelope *env;
1029  char *name_tmp;
1030  char *rd_ser;
1031  ssize_t rd_ser_len;
1032  size_t name_len;
1033  uint32_t rid;
1034  struct RecordStoreMessage *msg;
1035  ssize_t sret;
1036 
1037  name_len = strlen (label) + 1;
1038  if (name_len > MAX_NAME_LEN)
1039  {
1040  GNUNET_break (0);
1041  return NULL;
1042  }
1043  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1044  if (rd_ser_len < 0)
1045  {
1046  GNUNET_break (0);
1047  return NULL;
1048  }
1049  if (rd_ser_len > UINT16_MAX)
1050  {
1051  GNUNET_break (0);
1052  return NULL;
1053  }
1054  rid = get_op_id (h);
1056  qe->h = h;
1057  qe->cont = cont;
1058  qe->cont_cls = cont_cls;
1059  qe->op_id = rid;
1060  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1061 
1062  /* setup msg */
1064  name_len + rd_ser_len,
1066  msg->gns_header.r_id = htonl (rid);
1067  msg->name_len = htons (name_len);
1068  msg->rd_count = htons (rd_count);
1069  msg->rd_len = htons (rd_ser_len);
1070  msg->reserved = ntohs (0);
1071  msg->private_key = *pkey;
1072 
1073  name_tmp = (char *) &msg[1];
1074  GNUNET_memcpy (name_tmp, label, name_len);
1075  rd_ser = &name_tmp[name_len];
1076  sret = GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1077  if ((0 > sret) || (sret != rd_ser_len))
1078  {
1079  GNUNET_break (0);
1080  GNUNET_free (env);
1081  return NULL;
1082  }
1083  GNUNET_assert (rd_ser_len == sret);
1085  "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n",
1086  label,
1087  rd_count);
1088  qe->timeout_task =
1090  if (NULL == h->mq)
1091  {
1092  qe->env = env;
1094  "Delaying NAMESTORE_RECORD_STORE message as namestore is not ready!\n");
1095  }
1096  else
1097  {
1098  GNUNET_MQ_send (h->mq, env);
1099  }
1100  return qe;
1101 }
1102 
1108  struct GNUNET_NAMESTORE_Handle *h,
1109  const struct GNUNET_IDENTITY_PrivateKey *pkey,
1110  const char *label,
1111  unsigned int rd_count,
1112  const struct GNUNET_GNSRECORD_Data *rd,
1114  void *cont_cls)
1115 {
1116  return GNUNET_NAMESTORE_records_store (h, pkey, label, rd_count, rd,
1117  cont, cont_cls);
1118 }
1119 
1122  struct GNUNET_NAMESTORE_Handle *h,
1123  const struct GNUNET_IDENTITY_PrivateKey *pkey,
1124  const char *label,
1126  void *error_cb_cls,
1128  void *rm_cls)
1129 {
1131  struct GNUNET_MQ_Envelope *env;
1132  struct LabelLookupMessage *msg;
1133  size_t label_len;
1134 
1135  if (1 == (label_len = strlen (label) + 1))
1136  {
1137  GNUNET_break (0);
1138  return NULL;
1139  }
1140 
1142  qe->h = h;
1143  qe->error_cb = error_cb;
1144  qe->error_cb_cls = error_cb_cls;
1145  qe->proc = rm;
1146  qe->proc_cls = rm_cls;
1147  qe->op_id = get_op_id (h);
1148  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1149 
1151  label_len,
1153  msg->gns_header.r_id = htonl (qe->op_id);
1154  msg->zone = *pkey;
1155  msg->label_len = htonl (label_len);
1156  GNUNET_memcpy (&msg[1], label, label_len);
1157  if (NULL == h->mq)
1158  qe->env = env;
1159  else
1160  GNUNET_MQ_send (h->mq, env);
1161  return qe;
1162 }
1163 
1164 
1170  struct GNUNET_NAMESTORE_Handle *h,
1171  const struct GNUNET_IDENTITY_PrivateKey *pkey,
1172  const char *label,
1174  void *error_cb_cls,
1176  void *rm_cls)
1177 {
1178  return GNUNET_NAMESTORE_records_lookup (h, pkey, label,
1180  rm, rm_cls);
1181 }
1182 
1185  struct GNUNET_NAMESTORE_Handle *h,
1186  const struct GNUNET_IDENTITY_PrivateKey *zone,
1187  const struct GNUNET_IDENTITY_PublicKey *value_zone,
1189  void *error_cb_cls,
1191  void *proc_cls)
1192 {
1194  struct GNUNET_MQ_Envelope *env;
1195  struct ZoneToNameMessage *msg;
1196  uint32_t rid;
1197 
1198  rid = get_op_id (h);
1200  qe->h = h;
1201  qe->error_cb = error_cb;
1202  qe->error_cb_cls = error_cb_cls;
1203  qe->proc = proc;
1204  qe->proc_cls = proc_cls;
1205  qe->op_id = rid;
1206  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1207 
1209  msg->gns_header.r_id = htonl (rid);
1210  msg->zone = *zone;
1211  msg->value_zone = *value_zone;
1212  if (NULL == h->mq)
1213  qe->env = env;
1214  else
1215  GNUNET_MQ_send (h->mq, env);
1216  return qe;
1217 }
1218 
1219 
1241  struct GNUNET_NAMESTORE_Handle *h,
1242  const struct GNUNET_IDENTITY_PrivateKey *zone,
1244  void *error_cb_cls,
1246  void *proc_cls,
1248  void *finish_cb_cls)
1249 {
1250  struct GNUNET_NAMESTORE_ZoneIterator *it;
1251  struct GNUNET_MQ_Envelope *env;
1253  uint32_t rid;
1254 
1255  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1256  rid = get_op_id (h);
1258  it->h = h;
1259  it->error_cb = error_cb;
1260  it->error_cb_cls = error_cb_cls;
1261  it->finish_cb = finish_cb;
1262  it->finish_cb_cls = finish_cb_cls;
1263  it->proc = proc;
1264  it->proc_cls = proc_cls;
1265  it->op_id = rid;
1266  if (NULL != zone)
1267  it->zone = *zone;
1268  GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1270  msg->gns_header.r_id = htonl (rid);
1271  if (NULL != zone)
1272  msg->zone = *zone;
1273  if (NULL == h->mq)
1274  it->env = env;
1275  else
1276  GNUNET_MQ_send (h->mq, env);
1277  return it;
1278 }
1279 
1280 
1289 void
1291  uint64_t limit)
1292 {
1293  struct GNUNET_NAMESTORE_Handle *h = it->h;
1294  struct ZoneIterationNextMessage *msg;
1295  struct GNUNET_MQ_Envelope *env;
1296 
1298  "Sending ZONE_ITERATION_NEXT message with limit %llu\n",
1299  (unsigned long long) limit);
1301  msg->gns_header.r_id = htonl (it->op_id);
1302  msg->limit = GNUNET_htonll (limit);
1303  GNUNET_MQ_send (h->mq, env);
1304 }
1305 
1306 
1312 void
1314 {
1315  struct GNUNET_NAMESTORE_Handle *h = it->h;
1316  struct GNUNET_MQ_Envelope *env;
1317  struct ZoneIterationStopMessage *msg;
1318 
1319  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_STOP message\n");
1320  if (NULL != h->mq)
1321  {
1322  env =
1324  msg->gns_header.r_id = htonl (it->op_id);
1325  GNUNET_MQ_send (h->mq, env);
1326  }
1327  free_ze (it);
1328 }
1329 
1330 
1337 void
1339 {
1340  free_qe (qe);
1341 }
1342 
1350  void *error_cb_cls)
1351 {
1352  GNUNET_break (0);
1353  return NULL;
1354 }
1355 
1356 
1360  void *error_cb_cls)
1361 {
1362  GNUNET_break (0);
1363  return NULL;
1364 }
1365 
1366 
1380  void *error_cb_cls)
1381 {
1382  GNUNET_break (0);
1383  return NULL;
1384 }
1385 
1386 
1387 /* end of namestore_api.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static void error_cb(void *cls)
Function called if lookup fails.
Definition: gnunet-abd.c:479
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int res
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_DATASTORE_QueueEntry * qe
Current operation.
static char * pkey
Public key of the zone to look in, in ASCII.
static char * zone
Name of the zone being managed.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
cryptographic primitives for GNUnet
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:1066
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:302
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:283
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:685
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_replace(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
TODO: Experimental API will replace API above.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_select(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls)
TODO experimental API.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *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).
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *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.
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.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
void(* GNUNET_NAMESTORE_ContinuationWithStatus)(void *cls, int32_t success, const char *emsg)
Continuation called to notify client about result of the operation.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_transaction_commit(struct GNUNET_NAMESTORE_Handle *h, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls)
Commit a namestore transaction.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *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.
void(* GNUNET_NAMESTORE_RecordMonitor)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in 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_QueueEntry * GNUNET_NAMESTORE_transaction_begin(struct GNUNET_NAMESTORE_Handle *h, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls)
New API draft.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_transaction_abort(struct GNUNET_NAMESTORE_Handle *h, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls)
Begin rollback all actions in a transaction.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *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.
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP
Client to service: stop iterating.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
Client to service: store records (as authority)
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
Client to service: "reverse" lookup for zone name based on zone key.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP
Client to service: lookup label.
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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:1269
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:570
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
common internal definitions for namestore service
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.
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.
static struct GNUNET_NAMESTORE_QueueEntry * find_qe(struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
Find the queue entry that matches the rid.
#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
static void free_qe(struct GNUNET_NAMESTORE_QueueEntry *qe)
Free qe.
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.
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...
static int check_record_result(void *cls, const struct RecordResultMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
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.
static void free_ze(struct GNUNET_NAMESTORE_ZoneIterator *ze)
Free ze.
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...
static int check_rd(size_t rd_len, const void *rd_buf, unsigned int rd_count)
Check that rd_buf of length rd_len contains rd_count records.
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.
static void handle_lookup_result(void *cls, const struct LabelLookupResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
static void reconnect(struct GNUNET_NAMESTORE_Handle *h)
Reconnect to namestore service.
static void force_reconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from service and then reconnect.
#define LOG(kind,...)
Definition: namestore_api.c:41
static int check_record_store_response(void *cls, const struct RecordStoreResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
static struct GNUNET_NAMESTORE_ZoneIterator * find_zi(struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
Find the zone iteration entry that matches the rid.
static uint32_t get_op_id(struct GNUNET_NAMESTORE_Handle *h)
Get a fresh operation id to distinguish between namestore requests.
static void handle_record_result(void *cls, const struct RecordResultMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
static void reconnect_task(void *cls)
Re-establish the connection to the service.
const char * name
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:112
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:147
struct GNUNET_DATASTORE_Handle * h
Handle to the master context.
struct GNUNET_MQ_Envelope * env
Envelope of the request to transmit, NULL after transmission.
struct GNUNET_DATASTORE_QueueEntry * next
This is a linked list.
GNUNET_DATASTORE_ContinuationWithStatus cont
Function to call after transmission of the request.
void * cont_cls
Closure for cont.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Connection to the NAMESTORE service.
uint32_t last_op_id_used
The last operation id used for a NAMESTORE operation.
struct GNUNET_NAMESTORE_ZoneIterator * z_head
Head of pending namestore zone iterator entries.
struct GNUNET_NAMESTORE_QueueEntry * op_tail
Tail of pending namestore queue entries.
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
struct GNUNET_NAMESTORE_QueueEntry * op_head
Head of pending namestore queue entries.
struct GNUNET_TIME_Relative reconnect_delay
Delay introduced before we reconnect.
struct GNUNET_NAMESTORE_ZoneIterator * z_tail
Tail of pending namestore zone iterator entries.
int reconnect
Should we reconnect to service due to some serious error?
struct GNUNET_MQ_Handle * mq
Connection to the service (if available).
Generic namestore message with op id.
Definition: namestore.h:41
An QueueEntry used to store information for a pending NAMESTORE record operation.
Definition: namestore_api.c:54
struct GNUNET_MQ_Envelope * env
Envelope of the message to send to the service, if not yet sent.
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.
void * error_cb_cls
Closure for error_cb.
Definition: namestore_api.c:98
GNUNET_NAMESTORE_RecordMonitor proc
Function to call with the records we get back; or NULL.
Definition: namestore_api.c:83
struct GNUNET_NAMESTORE_QueueEntry * next
Kept in a DLL.
Definition: namestore_api.c:58
struct GNUNET_NAMESTORE_Handle * h
Main handle to access the namestore.
Definition: namestore_api.c:68
GNUNET_NAMESTORE_ContinuationWithStatus cont
Continuation to call.
Definition: namestore_api.c:73
struct GNUNET_SCHEDULER_Task * timeout_task
Task scheduled to warn us if the namestore is way too slow.
void * cont_cls
Closure for cont.
Definition: namestore_api.c:78
void * proc_cls
Closure for proc.
Definition: namestore_api.c:88
GNUNET_SCHEDULER_TaskCallback error_cb
Function to call on errors.
Definition: namestore_api.c:93
Handle for a zone iterator operation.
void * finish_cb_cls
Closure for error_cb.
void * error_cb_cls
Closure for error_cb.
struct GNUNET_NAMESTORE_ZoneIterator * next
Kept in a DLL.
struct GNUNET_NAMESTORE_Handle * h
Main handle to access the namestore.
void * proc_cls
Closure for proc.
uint32_t op_id
The operation id this zone iteration operation has.
struct GNUNET_IDENTITY_PrivateKey zone
Private key of the zone.
GNUNET_NAMESTORE_RecordMonitor proc
The continuation to call with the results.
GNUNET_SCHEDULER_TaskCallback error_cb
Function to call on errors.
struct GNUNET_MQ_Envelope * env
Envelope of the message to send to the service, if not yet sent.
GNUNET_SCHEDULER_TaskCallback finish_cb
Function to call on completion.
struct GNUNET_NAMESTORE_ZoneIterator * prev
Kept in a DLL.
Entry in list of pending tasks.
Definition: scheduler.c:135
Time for relative time used by GNUnet, in microseconds.
Lookup a label.
Definition: namestore.h:137
uint32_t label_len
Length of the name.
Definition: namestore.h:146
Record is returned from the namestore (as authority).
Definition: namestore.h:271
Store a record to the namestore (as authority).
Definition: namestore.h:59
uint16_t rd_count
Number of records contained.
Definition: namestore.h:83
uint16_t name_len
Name length.
Definition: namestore.h:73
Response to a record storage request.
Definition: namestore.h:106
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:377
Start a zone iteration for the given zone.
Definition: namestore.h:360
Stop zone iteration for the given operation.
Definition: namestore.h:396
Lookup a name for a zone hash.
Definition: namestore.h:206
struct GNUNET_IDENTITY_PublicKey value_zone
The public key of the target zone.
Definition: namestore.h:220
Respone for zone to name lookup.
Definition: namestore.h:228