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) \
39  GNUNET_log_from_strerror_file(kind, "util", syscall, filename)
40 
44 #define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
45 
49 #define NC_SIZE 16
50 
54 struct NamestoreClient;
55 
56 
60 struct ZoneIteration {
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 
132 
137 
143 
149 };
150 
151 
155 struct ZoneMonitor {
159  struct ZoneMonitor *next;
160 
164  struct ZoneMonitor *prev;
165 
170 
175 
180 
185 
189  struct GNUNET_TIME_Absolute sa_waiting_start;
190 
198  uint64_t seq;
199 
204  uint64_t limit;
205 
212  uint64_t iteration_cnt;
213 
218 
226 };
227 
228 
237 
242 
247 
252 
257  struct ZoneIteration *zi;
258 
262  uint32_t rid;
263 };
264 
265 
275 
280 
285 
290  const struct RecordStoreMessage *rsm;
291 
296 
300  char *conv_name;
301 };
302 
303 
307 struct NickCache {
312 
317 
321  struct GNUNET_TIME_Absolute last_used;
322 };
323 
324 
328 static struct NickCache nick_cache[NC_SIZE];
329 
334 
339 
344 
349 
354 
358 static char *db_lib_name;
359 
363 static struct CacheOperation *cop_head;
364 
368 static struct CacheOperation *cop_tail;
369 
373 static struct ZoneMonitor *monitor_head;
374 
378 static struct ZoneMonitor *monitor_tail;
379 
383 static struct StoreActivity *sa_head;
384 
388 static struct StoreActivity *sa_tail;
389 
394 
399 static int cache_keys;
400 
405 static int disable_namecache;
406 
407 
413 static void
414 cleanup_task(void *cls)
415 {
416  struct CacheOperation *cop;
417 
418  (void)cls;
419  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
420  while (NULL != (cop = cop_head))
421  {
423  "Aborting incomplete namecache operation\n");
425  GNUNET_CONTAINER_DLL_remove(cop_head, cop_tail, cop);
426  GNUNET_free(cop);
427  }
428  if (NULL != namecache)
429  {
430  GNUNET_NAMECACHE_disconnect(namecache);
431  namecache = NULL;
432  }
433  GNUNET_break(NULL == GNUNET_PLUGIN_unload(db_lib_name, GSN_database));
435  db_lib_name = NULL;
436  if (NULL != monitor_nc)
437  {
439  monitor_nc = NULL;
440  }
441  if (NULL != statistics)
442  {
444  statistics = NULL;
445  }
446 }
447 
448 
454 static void
456 {
457  GNUNET_CONTAINER_DLL_remove(sa_head, sa_tail, sa);
458  GNUNET_free(sa->conv_name);
459  GNUNET_free(sa);
460 }
461 
462 
475 static void
476 lookup_nick_it(void *cls,
477  uint64_t seq,
478  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
479  const char *label,
480  unsigned int rd_count,
481  const struct GNUNET_GNSRECORD_Data *rd)
482 {
483  struct GNUNET_GNSRECORD_Data **res = cls;
484 
485  (void)private_key;
486  GNUNET_assert(0 != seq);
487  if (0 != strcmp(label, GNUNET_GNS_EMPTY_LABEL_AT))
488  {
489  GNUNET_break(0);
490  return;
491  }
492  for (unsigned int c = 0; c < rd_count; c++)
493  {
495  {
496  (*res) =
497  GNUNET_malloc(rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
498  (*res)->data = &(*res)[1];
499  GNUNET_memcpy((void *)(*res)->data, rd[c].data, rd[c].data_size);
500  (*res)->data_size = rd[c].data_size;
501  (*res)->expiration_time = rd[c].expiration_time;
502  (*res)->flags = rd[c].flags;
503  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
504  return;
505  }
506  }
507  (*res) = NULL;
508 }
509 
510 
517 static void
519  const struct GNUNET_GNSRECORD_Data *nick)
520 {
521  struct NickCache *oldest;
522 
523  oldest = NULL;
524  for (unsigned int i = 0; i < NC_SIZE; i++)
525  {
526  struct NickCache *pos = &nick_cache[i];
527 
528  if ((NULL == oldest) ||
529  (oldest->last_used.abs_value_us > pos->last_used.abs_value_us))
530  oldest = pos;
531  if (0 == GNUNET_memcmp(zone, &pos->zone))
532  {
533  oldest = pos;
534  break;
535  }
536  }
537  GNUNET_free_non_null(oldest->rd);
538  oldest->zone = *zone;
539  if (NULL != nick)
540  {
541  oldest->rd = GNUNET_malloc(sizeof(*nick) + nick->data_size);
542  *oldest->rd = *nick;
543  oldest->rd->data = &oldest->rd[1];
544  memcpy(&oldest->rd[1], nick->data, nick->data_size);
545  }
546  else
547  {
548  oldest->rd = NULL;
549  }
551 }
552 
553 
560 static struct GNUNET_GNSRECORD_Data *
562 {
563  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
564  struct GNUNET_GNSRECORD_Data *nick;
565  int res;
566 
567  /* check cache first */
568  for (unsigned int i = 0; i < NC_SIZE; i++)
569  {
570  struct NickCache *pos = &nick_cache[i];
571  if ((NULL != pos->rd) && (0 == GNUNET_memcmp(zone, &pos->zone)))
572  {
573  if (NULL == pos->rd)
574  return NULL;
575  nick = GNUNET_malloc(sizeof(*nick) + pos->rd->data_size);
576  *nick = *pos->rd;
577  nick->data = &nick[1];
578  memcpy(&nick[1], pos->rd->data, pos->rd->data_size);
580  return nick;
581  }
582  }
583 
584  nick = NULL;
585  res = GSN_database->lookup_records(GSN_database->cls,
586  zone,
589  &nick);
590  if ((GNUNET_OK != res) || (NULL == nick))
591  {
592 #if !defined(GNUNET_CULL_LOGGING)
593  static int do_log = GNUNET_LOG_CALL_STATUS;
594 
595  if (0 == do_log)
597  "namestore",
598  __FILE__,
599  __FUNCTION__,
600  __LINE__);
601  if (1 == do_log)
602  {
605  "No nick name set for zone `%s'\n",
606  GNUNET_GNSRECORD_z2s(&pub));
607  }
608 #endif
609  /* update cache */
610  cache_nick(zone, NULL);
611  return NULL;
612  }
613 
614  /* update cache */
615  cache_nick(zone, nick);
616  return nick;
617 }
618 
619 
635 static void
637  unsigned int rd2_length,
638  const struct GNUNET_GNSRECORD_Data *rd2,
639  unsigned int *rdc_res,
640  struct GNUNET_GNSRECORD_Data **rd_res)
641 {
642  uint64_t latest_expiration;
643  size_t req;
644  char *data;
645  size_t data_offset;
646  struct GNUNET_GNSRECORD_Data *target;
647 
648  (*rdc_res) = 1 + rd2_length;
649  if (0 == 1 + rd2_length)
650  {
651  GNUNET_break(0);
652  (*rd_res) = NULL;
653  return;
654  }
655  req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
656  for (unsigned int i = 0; i < rd2_length; i++)
657  {
658  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
659 
660  if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
661  {
662  GNUNET_break(0);
663  (*rd_res) = NULL;
664  return;
665  }
666  req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
667  }
668  target = GNUNET_malloc(req);
669  (*rd_res) = target;
670  data = (char *)&target[1 + rd2_length];
671  data_offset = 0;
672  latest_expiration = 0;
673  for (unsigned int i = 0; i < rd2_length; i++)
674  {
675  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
676 
678  {
679  if ((GNUNET_TIME_absolute_get().abs_value_us + orig->expiration_time) >
680  latest_expiration)
681  latest_expiration = orig->expiration_time;
682  }
683  else if (orig->expiration_time > latest_expiration)
684  latest_expiration = orig->expiration_time;
685  target[i] = *orig;
686  target[i].data = (void *)&data[data_offset];
687  GNUNET_memcpy(&data[data_offset], orig->data, orig->data_size);
688  data_offset += orig->data_size;
689  }
690  /* append nick */
691  target[rd2_length] = *nick_rd;
692  target[rd2_length].expiration_time = latest_expiration;
693  target[rd2_length].data = (void *)&data[data_offset];
694  GNUNET_memcpy(&data[data_offset], nick_rd->data, nick_rd->data_size);
695  data_offset += nick_rd->data_size;
696  GNUNET_assert(req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res) +
697  data_offset);
698 }
699 
700 
712 static void
714  uint32_t request_id,
715  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
716  const char *name,
717  unsigned int rd_count,
718  const struct GNUNET_GNSRECORD_Data *rd)
719 {
720  struct GNUNET_MQ_Envelope *env;
721  struct RecordResultMessage *zir_msg;
722  struct GNUNET_GNSRECORD_Data *nick;
723  struct GNUNET_GNSRECORD_Data *res;
724  unsigned int res_count;
725  size_t name_len;
726  ssize_t rd_ser_len;
727  char *name_tmp;
728  char *rd_ser;
729 
730  nick = get_nick_record(zone_key);
732 
733  if ((NULL != nick) && (0 != strcmp(name, GNUNET_GNS_EMPTY_LABEL_AT)))
734  {
735  nick->flags =
737  merge_with_nick_records(nick, rd_count, rd, &res_count, &res);
738  GNUNET_free(nick);
739  }
740  else
741  {
742  res_count = rd_count;
743  res = (struct GNUNET_GNSRECORD_Data *)rd;
744  }
745 
746  GNUNET_assert(-1 != GNUNET_GNSRECORD_records_get_size(res_count, res));
747 
748 
749  name_len = strlen(name) + 1;
750  rd_ser_len = GNUNET_GNSRECORD_records_get_size(res_count, res);
751  if (rd_ser_len < 0)
752  {
753  GNUNET_break(0);
755  return;
756  }
757  if (((size_t)rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
758  {
759  GNUNET_break(0);
761  return;
762  }
763  env = GNUNET_MQ_msg_extra(zir_msg,
764  name_len + rd_ser_len,
766  zir_msg->gns_header.r_id = htonl(request_id);
767  zir_msg->name_len = htons(name_len);
768  zir_msg->rd_count = htons(res_count);
769  zir_msg->rd_len = htons((uint16_t)rd_ser_len);
770  zir_msg->private_key = *zone_key;
771  name_tmp = (char *)&zir_msg[1];
772  GNUNET_memcpy(name_tmp, name, name_len);
773  rd_ser = &name_tmp[name_len];
775  rd_ser_len ==
776  GNUNET_GNSRECORD_records_serialize(res_count, res, rd_ser_len, rd_ser));
778  "Sending RECORD_RESULT message with %u records\n",
779  res_count);
780  GNUNET_STATISTICS_update(statistics,
781  "Record sets sent to clients",
782  1,
783  GNUNET_NO);
784  GNUNET_MQ_send(nc->mq, env);
785  if (rd != res)
786  GNUNET_free(res);
787 }
788 
789 
797 static void
798 send_store_response(struct NamestoreClient *nc, int res, uint32_t rid)
799 {
800  struct GNUNET_MQ_Envelope *env;
801  struct RecordStoreResponseMessage *rcr_msg;
802 
803  GNUNET_assert(NULL != nc);
805  "Sending RECORD_STORE_RESPONSE message\n");
806  GNUNET_STATISTICS_update(statistics,
807  "Store requests completed",
808  1,
809  GNUNET_NO);
810  env = GNUNET_MQ_msg(rcr_msg,
812  rcr_msg->gns_header.r_id = htonl(rid);
813  rcr_msg->op_result = htonl(res);
814  GNUNET_MQ_send(nc->mq, env);
815 }
816 
817 
824 static void
826 {
827  struct GNUNET_MQ_Envelope *env;
828  struct GNUNET_NAMESTORE_Header *em;
829 
831  if (!zi->send_end)
832  return;
833  /* send empty response to indicate end of list */
835  em->r_id = htonl(zi->request_id);
836  GNUNET_MQ_send(zi->nc->mq, env);
837 
839  GNUNET_free(zi);
840 }
841 
842 
850 static void
851 finish_cache_operation(void *cls, int32_t success, const char *emsg)
852 {
853  struct CacheOperation *cop = cls;
854  struct ZoneIteration *zi;
855 
856  if (NULL != emsg)
858  _("Failed to replicate block in namecache: %s\n"),
859  emsg);
860  else
861  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
862  GNUNET_CONTAINER_DLL_remove(cop_head, cop_tail, cop);
863  if (NULL != cop->nc)
864  send_store_response(cop->nc, success, cop->rid);
865  if (NULL != (zi = cop->zi))
866  {
867  zi->cache_ops--;
868  if (0 == zi->cache_ops)
869  {
870  /* unchoke zone iteration, cache has caught up */
872  }
873  }
874  GNUNET_free(cop);
875 }
876 
877 
890 static void
892  struct ZoneIteration *zi,
893  uint32_t rid,
894  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
895  const char *name,
896  unsigned int rd_count,
897  const struct GNUNET_GNSRECORD_Data *rd)
898 {
899  struct GNUNET_GNSRECORD_Block *block;
900  struct CacheOperation *cop;
901  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
902  struct GNUNET_GNSRECORD_Data *nick;
903  struct GNUNET_GNSRECORD_Data *res;
904  unsigned int res_count;
905  struct GNUNET_TIME_Absolute exp_time;
906 
907  nick = get_nick_record(zone_key);
908  res_count = rd_count;
909  res = (struct GNUNET_GNSRECORD_Data *)rd; /* fixme: a bit unclean... */
910  if (NULL != nick)
911  {
912  nick->flags =
914  merge_with_nick_records(nick, rd_count, rd, &res_count, &res);
915  GNUNET_free(nick);
916  }
917  if (0 == res_count)
918  {
919  if (NULL != nc)
920  send_store_response(nc, GNUNET_OK, rid);
921  return; /* no data, no need to update cache */
922  }
924  {
925  GNUNET_STATISTICS_update(statistics,
926  "Namecache updates skipped (NC disabled)",
927  1,
928  GNUNET_NO);
929  if (NULL != nc)
930  send_store_response(nc, GNUNET_OK, rid);
931  return;
932  }
933  exp_time = GNUNET_GNSRECORD_record_get_expiration_time(res_count, res);
934  if (cache_keys)
935  block =
936  GNUNET_GNSRECORD_block_create2(zone_key, exp_time, name, res, res_count);
937  else
938  block =
939  GNUNET_GNSRECORD_block_create(zone_key, exp_time, name, res, res_count);
940  GNUNET_assert(NULL != block);
941  GNUNET_CRYPTO_ecdsa_key_get_public(zone_key, &pkey);
942  GNUNET_log(
944  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
945  name,
946  res_count,
948  GNUNET_GNSRECORD_z2s(&pkey));
949  GNUNET_STATISTICS_update(statistics,
950  "Namecache updates pushed",
951  1,
952  GNUNET_NO);
953  cop = GNUNET_new(struct CacheOperation);
954  cop->nc = nc;
955  cop->zi = zi;
956  if (NULL != zi)
957  zi->cache_ops++;
958  cop->rid = rid;
959  GNUNET_CONTAINER_DLL_insert(cop_head, cop_tail, cop);
960  cop->qe = GNUNET_NAMECACHE_block_cache(namecache,
961  block,
963  cop);
964  GNUNET_free(block);
965 }
966 
967 
973 static void
975 {
976  struct ZoneMonitor *zm = cls;
977 
979  "No response from monitor since %s\n",
983  zm);
984 }
985 
986 
992 static void
994 {
995  const struct RecordStoreMessage *rp_msg = sa->rsm;
996  unsigned int rd_count;
997  size_t name_len;
998  size_t rd_ser_len;
999  uint32_t rid;
1000  const char *name_tmp;
1001  const char *rd_ser;
1002 
1003  rid = ntohl(rp_msg->gns_header.r_id);
1004  name_len = ntohs(rp_msg->name_len);
1005  rd_count = ntohs(rp_msg->rd_count);
1006  rd_ser_len = ntohs(rp_msg->rd_len);
1007  name_tmp = (const char *)&rp_msg[1];
1008  rd_ser = &name_tmp[name_len];
1009  {
1010  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)];
1011 
1012  /* We did this before, must succeed again */
1013  GNUNET_assert(
1014  GNUNET_OK ==
1015  GNUNET_GNSRECORD_records_deserialize(rd_ser_len, rd_ser, rd_count, rd));
1016 
1017  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1018  {
1019  if ((0 != GNUNET_memcmp(&rp_msg->private_key, &zm->zone)) &&
1020  (0 != GNUNET_memcmp(&zm->zone, &zero)))
1021  {
1022  sa->zm_pos = zm->next; /* not interesting to this monitor */
1023  continue;
1024  }
1025  if (zm->limit == zm->iteration_cnt)
1026  {
1027  zm->sa_waiting = GNUNET_YES;
1028  zm->sa_waiting_start = GNUNET_TIME_absolute_get();
1029  if (NULL != zm->sa_wait_warning)
1030  GNUNET_SCHEDULER_cancel(zm->sa_wait_warning);
1031  zm->sa_wait_warning =
1034  zm);
1035  return; /* blocked on zone monitor */
1036  }
1038  "Notifying monitor about changes under label `%s'\n",
1039  sa->conv_name);
1040  zm->limit--;
1042  0,
1043  &rp_msg->private_key,
1044  sa->conv_name,
1045  rd_count,
1046  rd);
1047  sa->zm_pos = zm->next;
1048  }
1049  /* great, done with the monitors, unpack (again) for refresh_block operation */
1050  refresh_block(sa->nc,
1051  NULL,
1052  rid,
1053  &rp_msg->private_key,
1054  sa->conv_name,
1055  rd_count,
1056  rd);
1057  }
1059  free_store_activity(sa);
1060 }
1061 
1062 
1071 static void
1073  struct GNUNET_SERVICE_Client *client,
1074  void *app_ctx)
1075 {
1076  struct NamestoreClient *nc = app_ctx;
1077  struct ZoneIteration *no;
1078  struct CacheOperation *cop;
1079 
1080  (void)cls;
1081  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1082  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1083  {
1084  struct StoreActivity *san;
1085 
1086  if (nc != zm->nc)
1087  continue;
1088  GNUNET_CONTAINER_DLL_remove(monitor_head, monitor_tail, zm);
1089  if (NULL != zm->task)
1090  {
1091  GNUNET_SCHEDULER_cancel(zm->task);
1092  zm->task = NULL;
1093  }
1094  if (NULL != zm->sa_wait_warning)
1095  {
1096  GNUNET_SCHEDULER_cancel(zm->sa_wait_warning);
1097  zm->sa_wait_warning = NULL;
1098  }
1099  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1100  {
1101  san = sa->next;
1102  if (zm == sa->zm_pos)
1103  {
1104  sa->zm_pos = zm->next;
1105  /* this may free sa */
1107  }
1108  }
1109  GNUNET_free(zm);
1110  break;
1111  }
1112  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1113  {
1114  if (sa->nc == nc)
1115  {
1116  /* this may free sa */
1117  free_store_activity(sa);
1118  break; /* there can only be one per nc */
1119  }
1120  }
1121  while (NULL != (no = nc->op_head))
1122  {
1124  GNUNET_free(no);
1125  }
1126  for (cop = cop_head; NULL != cop; cop = cop->next)
1127  if (nc == cop->nc)
1128  cop->nc = NULL;
1129  GNUNET_free(nc);
1130 }
1131 
1132 
1141 static void *
1143  struct GNUNET_SERVICE_Client *client,
1144  struct GNUNET_MQ_Handle *mq)
1145 {
1146  struct NamestoreClient *nc;
1147 
1148  (void)cls;
1149  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1150  nc = GNUNET_new(struct NamestoreClient);
1151  nc->client = client;
1152  nc->mq = mq;
1153  return nc;
1154 }
1155 
1156 
1164  const char *label;
1165 
1169  char *res_rd;
1170 
1175 
1179  int found;
1180 
1184  unsigned int res_rd_count;
1185 
1189  ssize_t rd_ser_len;
1190 };
1191 
1192 
1205 static void
1206 lookup_it(void *cls,
1207  uint64_t seq,
1208  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
1209  const char *label,
1210  unsigned int rd_count,
1211  const struct GNUNET_GNSRECORD_Data *rd)
1212 {
1213  struct RecordLookupContext *rlc = cls;
1214 
1215  (void)private_key;
1216  GNUNET_assert(0 != seq);
1217  if (0 != strcmp(label, rlc->label))
1218  return;
1219  rlc->found = GNUNET_YES;
1220  if (0 == rd_count)
1221  {
1222  rlc->rd_ser_len = 0;
1223  rlc->res_rd_count = 0;
1224  rlc->res_rd = NULL;
1225  return;
1226  }
1227  if ((NULL != rlc->nick) && (0 != strcmp(label, GNUNET_GNS_EMPTY_LABEL_AT)))
1228  {
1229  /* Merge */
1230  struct GNUNET_GNSRECORD_Data *rd_res;
1231  unsigned int rdc_res;
1232 
1233  rd_res = NULL;
1234  rdc_res = 0;
1235  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^
1237  merge_with_nick_records(rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1238  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size(rdc_res, rd_res);
1239  if (rlc->rd_ser_len < 0)
1240  {
1241  GNUNET_break(0);
1242  GNUNET_free(rd_res);
1243  rlc->found = GNUNET_NO;
1244  rlc->rd_ser_len = 0;
1245  return;
1246  }
1247  rlc->res_rd_count = rdc_res;
1248  rlc->res_rd = GNUNET_malloc(rlc->rd_ser_len);
1249  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize(rdc_res,
1250  rd_res,
1251  rlc->rd_ser_len,
1252  rlc->res_rd))
1253  {
1254  GNUNET_break(0);
1255  GNUNET_free(rlc->res_rd);
1256  rlc->res_rd = NULL;
1257  rlc->res_rd_count = 0;
1258  rlc->rd_ser_len = 0;
1259  GNUNET_free(rd_res);
1260  rlc->found = GNUNET_NO;
1261  return;
1262  }
1263  GNUNET_free(rd_res);
1264  GNUNET_free(rlc->nick);
1265  rlc->nick = NULL;
1266  }
1267  else
1268  {
1269  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size(rd_count, rd);
1270  if (rlc->rd_ser_len < 0)
1271  {
1272  GNUNET_break(0);
1273  rlc->found = GNUNET_NO;
1274  rlc->rd_ser_len = 0;
1275  return;
1276  }
1277  rlc->res_rd_count = rd_count;
1278  rlc->res_rd = GNUNET_malloc(rlc->rd_ser_len);
1279  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize(rd_count,
1280  rd,
1281  rlc->rd_ser_len,
1282  rlc->res_rd))
1283  {
1284  GNUNET_break(0);
1285  GNUNET_free(rlc->res_rd);
1286  rlc->res_rd = NULL;
1287  rlc->res_rd_count = 0;
1288  rlc->rd_ser_len = 0;
1289  rlc->found = GNUNET_NO;
1290  return;
1291  }
1292  }
1293 }
1294 
1295 
1303 static int
1304 check_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
1305 {
1306  uint32_t name_len;
1307  size_t src_size;
1308 
1309  (void)cls;
1310  name_len = ntohl(ll_msg->label_len);
1311  src_size = ntohs(ll_msg->gns_header.header.size);
1312  if (name_len != src_size - sizeof(struct LabelLookupMessage))
1313  {
1314  GNUNET_break(0);
1315  return GNUNET_SYSERR;
1316  }
1318  return GNUNET_OK;
1319 }
1320 
1321 
1328 static void
1329 handle_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
1330 {
1331  struct NamestoreClient *nc = cls;
1332  struct GNUNET_MQ_Envelope *env;
1333  struct LabelLookupResponseMessage *llr_msg;
1334  struct RecordLookupContext rlc;
1335  const char *name_tmp;
1336  char *res_name;
1337  char *conv_name;
1338  uint32_t name_len;
1339  int res;
1340 
1341  name_len = ntohl(ll_msg->label_len);
1342  name_tmp = (const char *)&ll_msg[1];
1345  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1346  name_tmp);
1347 
1348  conv_name = GNUNET_GNSRECORD_string_to_lowercase(name_tmp);
1349  if (NULL == conv_name)
1350  {
1352  "Error converting name `%s'\n",
1353  name_tmp);
1355  return;
1356  }
1357  rlc.label = conv_name;
1358  rlc.found = GNUNET_NO;
1359  rlc.res_rd_count = 0;
1360  rlc.res_rd = NULL;
1361  rlc.rd_ser_len = 0;
1362  rlc.nick = get_nick_record(&ll_msg->zone);
1363  res = GSN_database->lookup_records(GSN_database->cls,
1364  &ll_msg->zone,
1365  conv_name,
1366  &lookup_it,
1367  &rlc);
1368  GNUNET_free(conv_name);
1369  env =
1370  GNUNET_MQ_msg_extra(llr_msg,
1371  name_len + rlc.rd_ser_len,
1373  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1374  llr_msg->private_key = ll_msg->zone;
1375  llr_msg->name_len = htons(name_len);
1376  llr_msg->rd_count = htons(rlc.res_rd_count);
1377  llr_msg->rd_len = htons(rlc.rd_ser_len);
1378  res_name = (char *)&llr_msg[1];
1379  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
1380  llr_msg->found = ntohs(GNUNET_YES);
1381  else
1382  llr_msg->found = ntohs(GNUNET_NO);
1383  GNUNET_memcpy(&llr_msg[1], name_tmp, name_len);
1384  GNUNET_memcpy(&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1385  GNUNET_MQ_send(nc->mq, env);
1387 }
1388 
1389 
1397 static int
1398 check_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
1399 {
1400  size_t name_len;
1401  size_t msg_size;
1402  size_t msg_size_exp;
1403  size_t rd_ser_len;
1404  const char *name_tmp;
1405 
1406  (void)cls;
1407  name_len = ntohs(rp_msg->name_len);
1408  msg_size = ntohs(rp_msg->gns_header.header.size);
1409  rd_ser_len = ntohs(rp_msg->rd_len);
1410  msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len;
1411  if (msg_size != msg_size_exp)
1412  {
1413  GNUNET_break(0);
1414  return GNUNET_SYSERR;
1415  }
1416  if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1417  {
1418  GNUNET_break(0);
1419  return GNUNET_SYSERR;
1420  }
1421  name_tmp = (const char *)&rp_msg[1];
1422  if ('\0' != name_tmp[name_len - 1])
1423  {
1424  GNUNET_break(0);
1425  return GNUNET_SYSERR;
1426  }
1427  return GNUNET_OK;
1428 }
1429 
1430 
1437 static void
1438 handle_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
1439 {
1440  struct NamestoreClient *nc = cls;
1441  size_t name_len;
1442  size_t rd_ser_len;
1443  uint32_t rid;
1444  const char *name_tmp;
1445  char *conv_name;
1446  const char *rd_ser;
1447  unsigned int rd_count;
1448  int res;
1449  struct StoreActivity *sa;
1450 
1452  "Received NAMESTORE_RECORD_STORE message\n");
1453  rid = ntohl(rp_msg->gns_header.r_id);
1454  name_len = ntohs(rp_msg->name_len);
1455  rd_count = ntohs(rp_msg->rd_count);
1456  rd_ser_len = ntohs(rp_msg->rd_len);
1457  GNUNET_break(0 == ntohs(rp_msg->reserved));
1458  name_tmp = (const char *)&rp_msg[1];
1459  rd_ser = &name_tmp[name_len];
1460  {
1461  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)];
1462 
1463  if (GNUNET_OK !=
1464  GNUNET_GNSRECORD_records_deserialize(rd_ser_len, rd_ser, rd_count, rd))
1465  {
1466  GNUNET_break(0);
1468  return;
1469  }
1470 
1471  /* Extracting and converting private key */
1472  conv_name = GNUNET_GNSRECORD_string_to_lowercase(name_tmp);
1473  if (NULL == conv_name)
1474  {
1476  "Error converting name `%s'\n",
1477  name_tmp);
1479  return;
1480  }
1481  GNUNET_STATISTICS_update(statistics,
1482  "Well-formed store requests received",
1483  1,
1484  GNUNET_NO);
1486  "Creating %u records for name `%s'\n",
1487  (unsigned int)rd_count,
1488  conv_name);
1489  if ((0 == rd_count) &&
1490  (GNUNET_NO == GSN_database->lookup_records(GSN_database->cls,
1491  &rp_msg->private_key,
1492  conv_name,
1493  NULL,
1494  0)))
1495  {
1496  /* This name does not exist, so cannot be removed */
1498  "Name `%s' does not exist, no deletion required\n",
1499  conv_name);
1500  res = GNUNET_NO;
1501  }
1502  else
1503  {
1504  /* remove "NICK" records, unless this is for the
1505  #GNUNET_GNS_EMPTY_LABEL_AT label */
1506  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL(rd_count)];
1507  unsigned int rd_clean_off;
1508  int have_nick;
1509 
1510  rd_clean_off = 0;
1511  have_nick = GNUNET_NO;
1512  for (unsigned int i = 0; i < rd_count; i++)
1513  {
1514  rd_clean[rd_clean_off] = rd[i];
1515  if ((0 == strcmp(GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1517  rd_clean_off++;
1518 
1519  if ((0 == strcmp(GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1520  (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
1521  {
1522  cache_nick(&rp_msg->private_key, &rd[i]);
1523  have_nick = GNUNET_YES;
1524  }
1525  }
1526  if ((0 == strcmp(GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1527  (GNUNET_NO == have_nick))
1528  {
1529  /* remove nick record from cache, in case we have one there */
1530  cache_nick(&rp_msg->private_key, NULL);
1531  }
1532  res = GSN_database->store_records(GSN_database->cls,
1533  &rp_msg->private_key,
1534  conv_name,
1535  rd_clean_off,
1536  rd_clean);
1537  }
1538 
1539  if (GNUNET_OK != res)
1540  {
1541  /* store not successful, not need to tell monitors */
1542  send_store_response(nc, res, rid);
1544  GNUNET_free(conv_name);
1545  return;
1546  }
1547 
1548  sa = GNUNET_malloc(sizeof(struct StoreActivity) +
1549  ntohs(rp_msg->gns_header.header.size));
1550  GNUNET_CONTAINER_DLL_insert(sa_head, sa_tail, sa);
1551  sa->nc = nc;
1552  sa->rsm = (const struct RecordStoreMessage *)&sa[1];
1553  GNUNET_memcpy(&sa[1], rp_msg, ntohs(rp_msg->gns_header.header.size));
1554  sa->zm_pos = monitor_head;
1555  sa->conv_name = conv_name;
1557  }
1558 }
1559 
1560 
1570 
1574  uint32_t rid;
1575 
1581  int success;
1582 };
1583 
1584 
1595 static void
1597  uint64_t seq,
1598  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1599  const char *name,
1600  unsigned int rd_count,
1601  const struct GNUNET_GNSRECORD_Data *rd)
1602 {
1603  struct ZoneToNameCtx *ztn_ctx = cls;
1604  struct GNUNET_MQ_Envelope *env;
1605  struct ZoneToNameResponseMessage *ztnr_msg;
1606  int16_t res;
1607  size_t name_len;
1608  ssize_t rd_ser_len;
1609  size_t msg_size;
1610  char *name_tmp;
1611  char *rd_tmp;
1612 
1613  GNUNET_assert(0 != seq);
1615  "Found result for zone-to-name lookup: `%s'\n",
1616  name);
1617  res = GNUNET_YES;
1618  name_len = (NULL == name) ? 0 : strlen(name) + 1;
1619  rd_ser_len = GNUNET_GNSRECORD_records_get_size(rd_count, rd);
1620  if (rd_ser_len < 0)
1621  {
1622  GNUNET_break(0);
1623  ztn_ctx->success = GNUNET_SYSERR;
1624  return;
1625  }
1626  msg_size = sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1627  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1628  {
1629  GNUNET_break(0);
1630  ztn_ctx->success = GNUNET_SYSERR;
1631  return;
1632  }
1633  env =
1634  GNUNET_MQ_msg_extra(ztnr_msg,
1635  name_len + rd_ser_len,
1637  ztnr_msg->gns_header.header.size = htons(msg_size);
1638  ztnr_msg->gns_header.r_id = htonl(ztn_ctx->rid);
1639  ztnr_msg->res = htons(res);
1640  ztnr_msg->rd_len = htons(rd_ser_len);
1641  ztnr_msg->rd_count = htons(rd_count);
1642  ztnr_msg->name_len = htons(name_len);
1643  ztnr_msg->zone = *zone_key;
1644  name_tmp = (char *)&ztnr_msg[1];
1645  GNUNET_memcpy(name_tmp, name, name_len);
1646  rd_tmp = &name_tmp[name_len];
1647  GNUNET_assert(
1648  rd_ser_len ==
1649  GNUNET_GNSRECORD_records_serialize(rd_count, rd, rd_ser_len, rd_tmp));
1650  ztn_ctx->success = GNUNET_OK;
1651  GNUNET_MQ_send(ztn_ctx->nc->mq, env);
1652 }
1653 
1654 
1661 static void
1662 handle_zone_to_name(void *cls, const struct ZoneToNameMessage *ztn_msg)
1663 {
1664  struct NamestoreClient *nc = cls;
1665  struct ZoneToNameCtx ztn_ctx;
1666  struct GNUNET_MQ_Envelope *env;
1667  struct ZoneToNameResponseMessage *ztnr_msg;
1668 
1669  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
1670  ztn_ctx.rid = ntohl(ztn_msg->gns_header.r_id);
1671  ztn_ctx.nc = nc;
1672  ztn_ctx.success = GNUNET_NO;
1673  if (GNUNET_SYSERR == GSN_database->zone_to_name(GSN_database->cls,
1674  &ztn_msg->zone,
1675  &ztn_msg->value_zone,
1677  &ztn_ctx))
1678  {
1679  /* internal error, hang up instead of signalling something
1680  that might be wrong */
1681  GNUNET_break(0);
1683  return;
1684  }
1685  if (GNUNET_NO == ztn_ctx.success)
1686  {
1687  /* no result found, send empty response */
1689  "Found no result for zone-to-name lookup.\n");
1690  env = GNUNET_MQ_msg(ztnr_msg,
1692  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
1693  ztnr_msg->res = htons(GNUNET_NO);
1694  GNUNET_MQ_send(nc->mq, env);
1695  }
1697 }
1698 
1699 
1709 
1713  uint64_t limit;
1714 };
1715 
1716 
1727 static void
1729  uint64_t seq,
1730  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1731  const char *name,
1732  unsigned int rd_count,
1733  const struct GNUNET_GNSRECORD_Data *rd)
1734 {
1735  struct ZoneIterationProcResult *proc = cls;
1736  int do_refresh_block;
1737 
1738  GNUNET_assert(0 != seq);
1739  if ((NULL == zone_key) && (NULL == name))
1740  {
1741  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1742  return;
1743  }
1744  if ((NULL == zone_key) || (NULL == name))
1745  {
1746  /* what is this!? should never happen */
1747  GNUNET_break(0);
1748  return;
1749  }
1750  if (0 == proc->limit)
1751  {
1752  /* what is this!? should never happen */
1753  GNUNET_break(0);
1754  return;
1755  }
1756  proc->limit--;
1757  proc->zi->seq = seq;
1758  send_lookup_response(proc->zi->nc,
1759  proc->zi->request_id,
1760  zone_key,
1761  name,
1762  rd_count,
1763  rd);
1764 
1765 
1766  do_refresh_block = GNUNET_NO;
1767  for (unsigned int i = 0; i < rd_count; i++)
1768  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1769  {
1770  do_refresh_block = GNUNET_YES;
1771  break;
1772  }
1773  if (GNUNET_YES == do_refresh_block)
1774  refresh_block(NULL, proc->zi, 0, zone_key, name, rd_count, rd);
1775 }
1776 
1777 
1784 static void
1786 {
1787  struct ZoneIterationProcResult proc;
1788  struct GNUNET_TIME_Absolute start;
1789  struct GNUNET_TIME_Relative duration;
1790 
1791  memset(&proc, 0, sizeof(proc));
1793  "Asked to return up to %llu records at position %llu\n",
1794  (unsigned long long)limit,
1795  (unsigned long long)zi->seq);
1796  proc.zi = zi;
1797  proc.limit = limit;
1798  start = GNUNET_TIME_absolute_get();
1800  GSN_database->iterate_records(GSN_database->cls,
1801  (0 == GNUNET_is_zero(&zi->zone))
1802  ? NULL
1803  : &zi->zone,
1804  zi->seq,
1805  limit,
1807  &proc));
1808  duration = GNUNET_TIME_absolute_get_duration(start);
1809  duration = GNUNET_TIME_relative_divide(duration, limit - proc.limit);
1810  GNUNET_STATISTICS_set(statistics,
1811  "NAMESTORE iteration delay (μs/record)",
1812  duration.rel_value_us,
1813  GNUNET_NO);
1814  if (0 == proc.limit)
1816  "Returned %llu results, more results available\n",
1817  (unsigned long long)limit);
1818  zi->send_end = (0 != proc.limit);
1819  if (0 == zi->cache_ops)
1821 }
1822 
1823 
1830 static void
1832  const struct ZoneIterationStartMessage *zis_msg)
1833 {
1834  struct NamestoreClient *nc = cls;
1835  struct ZoneIteration *zi;
1836 
1838  "Received ZONE_ITERATION_START message\n");
1839  zi = GNUNET_new(struct ZoneIteration);
1840  zi->request_id = ntohl(zis_msg->gns_header.r_id);
1841  zi->offset = 0;
1842  zi->nc = nc;
1843  zi->zone = zis_msg->zone;
1844 
1846  run_zone_iteration_round(zi, 1);
1847 }
1848 
1849 
1856 static void
1858  const struct ZoneIterationStopMessage *zis_msg)
1859 {
1860  struct NamestoreClient *nc = cls;
1861  struct ZoneIteration *zi;
1862  uint32_t rid;
1863 
1865  "Received ZONE_ITERATION_STOP message\n");
1866  rid = ntohl(zis_msg->gns_header.r_id);
1867  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1868  if (zi->request_id == rid)
1869  break;
1870  if (NULL == zi)
1871  {
1872  GNUNET_break(0);
1874  return;
1875  }
1877  GNUNET_free(zi);
1879 }
1880 
1881 
1888 static void
1890  const struct ZoneIterationNextMessage *zis_msg)
1891 {
1892  struct NamestoreClient *nc = cls;
1893  struct ZoneIteration *zi;
1894  uint32_t rid;
1895  uint64_t limit;
1896 
1898  "Received ZONE_ITERATION_NEXT message\n");
1899  GNUNET_STATISTICS_update(statistics,
1900  "Iteration NEXT messages received",
1901  1,
1902  GNUNET_NO);
1903  rid = ntohl(zis_msg->gns_header.r_id);
1904  limit = GNUNET_ntohll(zis_msg->limit);
1905  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1906  if (zi->request_id == rid)
1907  break;
1908  if (NULL == zi)
1909  {
1910  GNUNET_break(0);
1912  return;
1913  }
1914  run_zone_iteration_round(zi, limit);
1915 }
1916 
1917 
1923 static void
1925 {
1926  struct StoreActivity *sa = sa_head;
1927 
1928  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
1929  {
1930  struct StoreActivity *sn = sa->next;
1931 
1932  if (sa->zm_pos == zm)
1934  sa = sn;
1935  }
1936  if (zm->limit > zm->iteration_cnt)
1937  {
1938  zm->sa_waiting = GNUNET_NO;
1939  if (NULL != zm->sa_wait_warning)
1940  {
1942  zm->sa_wait_warning = NULL;
1943  }
1944  }
1945  else if (GNUNET_YES == zm->sa_waiting)
1946  {
1948  if (NULL != zm->sa_wait_warning)
1950  zm->sa_wait_warning =
1953  zm);
1954  }
1955 }
1956 
1957 
1963 static void
1965 {
1966  struct GNUNET_MQ_Envelope *env;
1967  struct GNUNET_MessageHeader *sync;
1968 
1970  GNUNET_MQ_send(zm->nc->mq, env);
1971  /* mark iteration done */
1973  zm->iteration_cnt = 0;
1974  if ((zm->limit > 0) && (zm->sa_waiting))
1975  monitor_unblock(zm);
1976 }
1977 
1978 
1984 static void
1985 monitor_iteration_next(void *cls);
1986 
1987 
1998 static void
2000  uint64_t seq,
2001  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
2002  const char *name,
2003  unsigned int rd_count,
2004  const struct GNUNET_GNSRECORD_Data *rd)
2005 {
2006  struct ZoneMonitor *zm = cls;
2007 
2008  GNUNET_assert(0 != seq);
2009  zm->seq = seq;
2010  GNUNET_assert(NULL != name);
2011  GNUNET_STATISTICS_update(statistics,
2012  "Monitor notifications sent",
2013  1,
2014  GNUNET_NO);
2015  zm->limit--;
2016  zm->iteration_cnt--;
2017  send_lookup_response(zm->nc, 0, zone_key, name, rd_count, rd);
2018  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2019  {
2020  /* We are done with the current iteration batch, AND the
2021  client would right now accept more, so go again! */
2022  GNUNET_assert(NULL == zm->task);
2024  }
2025 }
2026 
2027 
2034 static void
2035 handle_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2036 {
2037  struct NamestoreClient *nc = cls;
2038  struct ZoneMonitor *zm;
2039 
2040  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_MONITOR_START message\n");
2041  zm = GNUNET_new(struct ZoneMonitor);
2042  zm->nc = nc;
2043  zm->zone = zis_msg->zone;
2044  zm->limit = 1;
2045  zm->in_first_iteration = (GNUNET_YES == ntohl(zis_msg->iterate_first));
2046  GNUNET_CONTAINER_DLL_insert(monitor_head, monitor_tail, zm);
2049  GNUNET_notification_context_add(monitor_nc, nc->mq);
2050  if (zm->in_first_iteration)
2052  else
2053  monitor_sync(zm);
2054 }
2055 
2056 
2062 static void
2064 {
2065  struct ZoneMonitor *zm = cls;
2066  int ret;
2067 
2068  zm->task = NULL;
2069  GNUNET_assert(0 == zm->iteration_cnt);
2070  if (zm->limit > 16)
2071  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2072  else
2073  zm->iteration_cnt = zm->limit; /* use it all */
2074  ret = GSN_database->iterate_records(GSN_database->cls,
2075  (0 == GNUNET_is_zero(&zm->zone))
2076  ? NULL
2077  : &zm->zone,
2078  zm->seq,
2079  zm->iteration_cnt,
2081  zm);
2082  if (GNUNET_SYSERR == ret)
2083  {
2085  return;
2086  }
2087  if (GNUNET_NO == ret)
2088  {
2089  /* empty zone */
2090  monitor_sync(zm);
2091  return;
2092  }
2093 }
2094 
2095 
2102 static void
2103 handle_monitor_next(void *cls, const struct ZoneMonitorNextMessage *nm)
2104 {
2105  struct NamestoreClient *nc = cls;
2106  struct ZoneMonitor *zm;
2107  uint64_t inc;
2108 
2109  inc = GNUNET_ntohll(nm->limit);
2111  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2112  (unsigned long long)inc);
2113  for (zm = monitor_head; NULL != zm; zm = zm->next)
2114  if (zm->nc == nc)
2115  break;
2116  if (NULL == zm)
2117  {
2118  GNUNET_break(0);
2120  return;
2121  }
2123  if (zm->limit + inc < zm->limit)
2124  {
2125  GNUNET_break(0);
2127  return;
2128  }
2129  zm->limit += inc;
2130  if ((zm->in_first_iteration) && (zm->limit == inc))
2131  {
2132  /* We are still iterating, and the previous iteration must
2133  have stopped due to the client's limit, so continue it! */
2134  GNUNET_assert(NULL == zm->task);
2136  }
2137  GNUNET_assert(zm->iteration_cnt <= zm->limit);
2138  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2139  {
2140  monitor_unblock(zm);
2141  }
2142  else if (GNUNET_YES == zm->sa_waiting)
2143  {
2144  if (NULL != zm->sa_wait_warning)
2147  zm->sa_wait_warning =
2150  zm);
2151  }
2152 }
2153 
2154 
2162 static void
2163 run(void *cls,
2164  const struct GNUNET_CONFIGURATION_Handle *cfg,
2166 {
2167  char *database;
2168 
2169  (void)cls;
2170  (void)service;
2171  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2172  cache_keys =
2173  GNUNET_CONFIGURATION_get_value_yesno(cfg, "namestore", "CACHE_KEYS");
2175  GNUNET_CONFIGURATION_get_value_yesno(cfg, "namecache", "DISABLE");
2176  GSN_cfg = cfg;
2177  monitor_nc = GNUNET_notification_context_create(1);
2179  {
2180  namecache = GNUNET_NAMECACHE_connect(cfg);
2181  GNUNET_assert(NULL != namecache);
2182  }
2183  /* Loading database plugin */
2185  "namestore",
2186  "database",
2187  &database))
2188  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2189 
2190  GNUNET_asprintf(&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2191  GSN_database = GNUNET_PLUGIN_load(db_lib_name, (void *)GSN_cfg);
2192  GNUNET_free(database);
2193  statistics = GNUNET_STATISTICS_create("namestore", cfg);
2195  if (NULL == GSN_database)
2196  {
2198  "Could not load database backend `%s'\n",
2199  db_lib_name);
2201  return;
2202  }
2203 }
2204 
2205 
2210  "namestore",
2212  &run,
2215  NULL,
2216  GNUNET_MQ_hd_var_size(record_store,
2218  struct RecordStoreMessage,
2219  NULL),
2220  GNUNET_MQ_hd_var_size(record_lookup,
2222  struct LabelLookupMessage,
2223  NULL),
2226  struct ZoneToNameMessage,
2227  NULL),
2231  NULL),
2232  GNUNET_MQ_hd_fixed_size(iteration_next,
2234  struct ZoneIterationNextMessage,
2235  NULL),
2236  GNUNET_MQ_hd_fixed_size(iteration_stop,
2238  struct ZoneIterationStopMessage,
2239  NULL),
2240  GNUNET_MQ_hd_fixed_size(monitor_start,
2242  struct ZoneMonitorStartMessage,
2243  NULL),
2244  GNUNET_MQ_hd_fixed_size(monitor_next,
2246  struct ZoneMonitorNextMessage,
2247  NULL),
2249 
2250 
2251 /* 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:107
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:61
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:74
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:291
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:128
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:114
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:353
struct GNUNET_NAMECACHE_QueueEntry * qe
Handle to namecache queue.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:158
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:1284
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:50
uint16_t rd_count
Number of records contained.
Definition: namestore.h:163
#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:337
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:191
uint16_t name_len
Length of the name.
Definition: namestore.h:217
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
struct ZoneMonitor * zm_pos
Next zone monitor that still needs to be notified about this PUT.
static 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:233
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
size_t data_size
Number of bytes in data.
struct StoreActivity * next
Kept in a DLL.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
static struct CacheOperation * cop_head
Head of cop DLL.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Information we have in an encrypted block with record data (i.e.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct NickCache nick_cache[16]
We cache nick records to reduce DB load.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
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:158
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:86
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone the cache entry is for.
int success
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
static void run_zone_iteration_round(struct ZoneIteration *zi, uint64_t limit)
Perform the next round of the zone iteration.
Entry in list of cached nick resolutions.
struct ZoneIteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint16_t name_len
Name length.
Definition: namestore.h:259
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:255
common internal definitions for namestore service
Handle to a client that is connected to a service.
Definition: service.c:246
uint16_t rd_count
Number of records contained.
Definition: namestore.h:227
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:112
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size ...
Definition: namestore.h:45
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:279
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:329
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:201
#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:1237
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:76
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:269
#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:1264
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:306
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:371
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:71
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:153
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2394
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:2315
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:341
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:81
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:238
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c: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:169
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:264
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:254
#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:301
#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:119
#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:313
Handle to a message queue.
Definition: mq.c:84
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:212
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:91
Store a record to the namestore (as authority).
Definition: namestore.h:57
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:208
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:196
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:148
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:83
Response to a record storage request.
Definition: namestore.h:103
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:93
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:174
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Key of the zone we are iterating over.
Entry in list of pending tasks.
Definition: scheduler.c:131
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:222
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:123
Lookup a name for a zone hash.
Definition: namestore.h:187
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:119
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:77
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:135
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:206
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:351
#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:250
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:364
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:741
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:346
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:357
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:2234
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:375
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:144
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:133
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:956
#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...