GNUnet  0.10.x
gnunet-service-datastore.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2004-2014, 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 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_protocols.h"
32 #include "datastore.h"
33 
37 #define MAX_PENDING 1024
38 
42 #define MAX_BF_SIZE ((uint32_t) (1LL << 31))
43 
48 #define MAX_EXPIRE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
49 
54 #define MIN_EXPIRE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
55 
59 static char *quota_stat_name;
60 
65 
70 #define MAX_STAT_SYNC_LAG 50
71 
72 
77 {
78 
84 
88  char *short_name;
89 
93  char *lib_name;
94 
100 
101 };
102 
103 
108 {
109 
114 
119 
123  uint64_t amount;
124 
128  uint64_t entries;
129 
133  int32_t rid;
134 
135 };
136 
137 
138 
142 static struct DatastorePlugin *plugin;
143 
148 
153 
157 static char *plugin_name;
158 
162 static const struct GNUNET_CONFIGURATION_Handle *cfg;
163 
168 
175 static unsigned long long cache_size;
176 
180 static unsigned long long reserved;
181 
186 static unsigned long long payload;
187 
193 
201 
205 static unsigned long long quota;
206 
210 static int do_drop;
211 
215 static int refresh_bf;
216 
222 static unsigned int last_sync;
223 
227 static int stats_worked;
228 
229 
234 static void
236 {
237  GNUNET_STATISTICS_set (stats,
239  payload,
240  GNUNET_YES);
241  GNUNET_STATISTICS_set (stats,
242  "# utilization by current datastore",
243  payload,
244  GNUNET_NO);
245  last_sync = 0;
246 }
247 
248 
253 static int cleaning_done;
254 
259 
264 
273 static void
274 delete_expired (void *cls);
275 
276 
298 static int
299 expired_processor (void *cls,
300  const struct GNUNET_HashCode *key,
301  uint32_t size,
302  const void *data,
303  enum GNUNET_BLOCK_Type type,
304  uint32_t priority,
305  uint32_t anonymity,
306  uint32_t replication,
308  uint64_t uid)
309 {
310  struct GNUNET_TIME_Absolute now;
311 
312  if (NULL == key)
313  {
314  expired_kill_task =
317  &delete_expired, NULL);
318  return GNUNET_SYSERR;
319  }
320  now = GNUNET_TIME_absolute_get ();
321  if (expiration.abs_value_us > now.abs_value_us)
322  {
323  /* finished processing */
324  expired_kill_task =
327  &delete_expired, NULL);
328  return GNUNET_SYSERR;
329  }
331  "Deleting content `%s' of type %u that expired %s ago\n",
332  GNUNET_h2s (key), type,
334  now),
335  GNUNET_YES));
336  min_expiration = now;
338  gettext_noop ("# bytes expired"),
339  size,
340  GNUNET_YES);
342  expired_kill_task =
345  &delete_expired, NULL);
346  return GNUNET_NO;
347 }
348 
349 
358 static void
359 delete_expired (void *cls)
360 {
361  expired_kill_task = NULL;
362  plugin->api->get_expiration (plugin->api->cls,
364  NULL);
365 }
366 
367 
387 static int
388 quota_processor (void *cls,
389  const struct GNUNET_HashCode *key,
390  uint32_t size,
391  const void *data,
392  enum GNUNET_BLOCK_Type type,
393  uint32_t priority,
394  uint32_t anonymity,
395  uint32_t replication,
397  uint64_t uid)
398 {
399  unsigned long long *need = cls;
400 
401  if (NULL == key)
402  return GNUNET_SYSERR;
404  "Deleting %llu bytes of low-priority (%u) content `%s' of type %u at %s prior to expiration (still trying to free another %llu bytes)\n",
405  (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD),
406  (unsigned int) priority,
407  GNUNET_h2s (key), type,
409  GNUNET_YES),
410  *need);
411  if (size + GNUNET_DATASTORE_ENTRY_OVERHEAD > *need)
412  *need = 0;
413  else
414  *need -= size + GNUNET_DATASTORE_ENTRY_OVERHEAD;
415  if (priority > 0)
417  else
420  gettext_noop ("# bytes purged (low-priority)"),
421  size, GNUNET_YES);
423  return GNUNET_NO;
424 }
425 
426 
439 static void
440 manage_space (unsigned long long need)
441 {
442  unsigned long long last;
443 
445  "Asked to free up %llu bytes of cache space\n",
446  need);
447  last = 0;
448  while ((need > 0) && (last != need))
449  {
450  last = need;
451  plugin->api->get_expiration (plugin->api->cls,
453  &need);
454  }
455 }
456 
457 
465 static void
467  int code,
468  const char *msg)
469 {
470  struct GNUNET_MQ_Envelope *env;
471  struct StatusMessage *sm;
472  size_t slen;
473 
475  "Transmitting `%s' message with value %d and message `%s'\n",
476  "STATUS", code, msg != NULL ? msg : "(none)");
477  slen = (msg == NULL) ? 0 : strlen (msg) + 1;
478  env = GNUNET_MQ_msg_extra (sm,
479  slen,
481  sm->status = htonl (code);
483  GNUNET_memcpy (&sm[1],
484  msg,
485  slen);
487  env);
488 }
489 
490 
509 static int
510 transmit_item (void *cls,
511  const struct GNUNET_HashCode *key,
512  uint32_t size,
513  const void *data,
514  enum GNUNET_BLOCK_Type type,
515  uint32_t priority,
516  uint32_t anonymity,
517  uint32_t replication,
519  uint64_t uid)
520 {
521  struct GNUNET_SERVICE_Client *client = cls;
522  struct GNUNET_MQ_Envelope *env;
523  struct GNUNET_MessageHeader *end;
524  struct DataMessage *dm;
525 
526  if (NULL == key)
527  {
528  /* transmit 'DATA_END' */
530  "Transmitting DATA_END message\n");
531  env = GNUNET_MQ_msg (end,
534  env);
535  return GNUNET_OK;
536  }
537  GNUNET_assert (sizeof (struct DataMessage) + size <
539  env = GNUNET_MQ_msg_extra (dm,
540  size,
542  dm->rid = htonl (0);
543  dm->size = htonl (size);
544  dm->type = htonl (type);
545  dm->priority = htonl (priority);
546  dm->anonymity = htonl (anonymity);
547  dm->replication = htonl (replication);
548  dm->expiration = GNUNET_TIME_absolute_hton (expiration);
549  dm->uid = GNUNET_htonll (uid);
550  dm->key = *key;
551  GNUNET_memcpy (&dm[1],
552  data,
553  size);
555  "Transmitting DATA message for `%s' of type %u with expiration %s (in: %s)\n",
556  GNUNET_h2s (key),
557  type,
560  GNUNET_YES));
562  gettext_noop ("# results found"),
563  1,
564  GNUNET_NO);
566  env);
567  return GNUNET_OK;
568 }
569 
570 
577 static void
578 handle_reserve (void *cls,
579  const struct ReserveMessage *msg)
580 {
584  static int reservation_gen;
585  struct GNUNET_SERVICE_Client *client = cls;
586  struct ReservationList *e;
587  unsigned long long used;
588  unsigned long long req;
589  uint64_t amount;
590  uint32_t entries;
591 
593  "Processing RESERVE request\n");
594  amount = GNUNET_ntohll (msg->amount);
595  entries = ntohl (msg->entries);
596  used = payload + reserved;
597  req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries;
598  if (used + req > quota)
599  {
600  if (quota < used)
601  used = quota; /* cheat a bit for error message (to avoid negative numbers) */
603  _("Insufficient space (%llu bytes are available) to satisfy RESERVE request for %llu bytes\n"),
604  quota - used,
605  req);
606  if (cache_size < req)
607  {
608  /* TODO: document this in the FAQ; essentially, if this
609  * message happens, the insertion request could be blocked
610  * by less-important content from migration because it is
611  * larger than 1/8th of the overall available space, and
612  * we only reserve 1/8th for "fresh" insertions */
614  _("The requested amount (%llu bytes) is larger than the cache size (%llu bytes)\n"),
615  req,
616  cache_size);
617  transmit_status (client,
618  0,
620  ("Insufficient space to satisfy request and "
621  "requested amount is larger than cache size"));
622  }
623  else
624  {
625  transmit_status (client,
626  0,
627  gettext_noop ("Insufficient space to satisfy request"));
628  }
630  return;
631  }
632  reserved += req;
633  GNUNET_STATISTICS_set (stats,
634  gettext_noop ("# reserved"),
635  reserved,
636  GNUNET_NO);
637  e = GNUNET_new (struct ReservationList);
638  e->next = reservations;
639  reservations = e;
640  e->client = client;
641  e->amount = amount;
642  e->entries = entries;
643  e->rid = ++reservation_gen;
644  if (reservation_gen < 0)
645  reservation_gen = 0; /* wrap around */
646  transmit_status (client,
647  e->rid,
648  NULL);
650 }
651 
652 
659 static void
661  const struct ReleaseReserveMessage *msg)
662 {
663  struct GNUNET_SERVICE_Client *client = cls;
664  struct ReservationList *pos;
665  struct ReservationList *prev;
666  struct ReservationList *next;
667  int rid = ntohl (msg->rid);
668  unsigned long long rem;
669 
671  "Processing RELEASE_RESERVE request\n");
672  next = reservations;
673  prev = NULL;
674  while (NULL != (pos = next))
675  {
676  next = pos->next;
677  if (rid == pos->rid)
678  {
679  if (prev == NULL)
680  reservations = next;
681  else
682  prev->next = next;
683  rem =
684  pos->amount +
685  ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries;
686  GNUNET_assert (reserved >= rem);
687  reserved -= rem;
688  GNUNET_STATISTICS_set (stats,
689  gettext_noop ("# reserved"),
690  reserved,
691  GNUNET_NO);
693  "Returning %llu remaining reserved bytes to storage pool\n",
694  rem);
695  GNUNET_free (pos);
696  transmit_status (client,
697  GNUNET_OK,
698  NULL);
700  return;
701  }
702  prev = pos;
703  }
704  GNUNET_break (0);
705  transmit_status (client,
707  gettext_noop ("Could not find matching reservation"));
709 }
710 
711 
718 static int
719 check_data (const struct DataMessage *dm)
720 {
721  uint16_t size;
722  uint32_t dsize;
723 
724  size = ntohs (dm->header.size);
725  dsize = ntohl (dm->size);
726  if (size != dsize + sizeof (struct DataMessage))
727  {
728  GNUNET_break (0);
729  return GNUNET_SYSERR;
730  }
731  return GNUNET_OK;
732 }
733 
734 
745 static void
746 put_continuation (void *cls,
747  const struct GNUNET_HashCode *key,
748  uint32_t size,
749  int status,
750  const char *msg)
751 {
752  struct GNUNET_SERVICE_Client *client = cls;
753 
754  if (GNUNET_OK == status)
755  {
757  gettext_noop ("# bytes stored"),
758  size,
759  GNUNET_YES);
761  key);
763  "Successfully stored %u bytes under key `%s'\n",
764  size,
765  GNUNET_h2s (key));
766  }
767  transmit_status (client,
768  GNUNET_SYSERR == status ? GNUNET_SYSERR : GNUNET_OK,
769  msg);
770  if (quota - reserved - cache_size < payload)
771  {
773  _("Need %llu bytes more space (%llu allowed, using %llu)\n"),
774  (unsigned long long) size + GNUNET_DATASTORE_ENTRY_OVERHEAD,
775  (unsigned long long) (quota - reserved - cache_size),
776  (unsigned long long) payload);
778  }
779 }
780 
781 
789 static int
790 check_put (void *cls,
791  const struct DataMessage *dm)
792 {
793  if (GNUNET_OK != check_data (dm))
794  {
795  GNUNET_break (0);
796  return GNUNET_SYSERR;
797  }
798  return GNUNET_OK;
799 }
800 
801 
808 static void
809 handle_put (void *cls,
810  const struct DataMessage *dm)
811 {
812  struct GNUNET_SERVICE_Client *client = cls;
813  int rid;
814  struct ReservationList *pos;
815  uint32_t size;
816 
818  "Processing PUT request for `%s' of type %u\n",
819  GNUNET_h2s (&dm->key),
820  (uint32_t) ntohl (dm->type));
821  rid = ntohl (dm->rid);
822  size = ntohl (dm->size);
823  if (rid > 0)
824  {
825  pos = reservations;
826  while ((NULL != pos) && (rid != pos->rid))
827  pos = pos->next;
828  GNUNET_break (pos != NULL);
829  if (NULL != pos)
830  {
831  GNUNET_break (pos->entries > 0);
832  GNUNET_break (pos->amount >= size);
833  pos->entries--;
834  pos->amount -= size;
836  GNUNET_STATISTICS_set (stats,
837  gettext_noop ("# reserved"),
838  reserved,
839  GNUNET_NO);
840  }
841  }
842  bool absent = GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (filter,
843  &dm->key);
844  plugin->api->put (plugin->api->cls,
845  &dm->key,
846  absent,
847  ntohl (dm->size),
848  &dm[1],
849  ntohl (dm->type),
850  ntohl (dm->priority),
851  ntohl (dm->anonymity),
852  ntohl (dm->replication),
855  client);
857 }
858 
859 
866 static void
867 handle_get (void *cls,
868  const struct GetMessage *msg)
869 {
870  struct GNUNET_SERVICE_Client *client = cls;
871 
873  "Processing GET request of type %u\n",
874  (uint32_t) ntohl (msg->type));
876  gettext_noop ("# GET requests received"),
877  1,
878  GNUNET_NO);
879  plugin->api->get_key (plugin->api->cls,
880  GNUNET_ntohll (msg->next_uid),
881  msg->random,
882  NULL,
883  ntohl (msg->type),
884  &transmit_item,
885  client);
887 }
888 
889 
896 static void
897 handle_get_key (void *cls,
898  const struct GetKeyMessage *msg)
899 {
900  struct GNUNET_SERVICE_Client *client = cls;
901 
903  "Processing GET request for `%s' of type %u\n",
904  GNUNET_h2s (&msg->key),
905  (uint32_t) ntohl (msg->type));
907  gettext_noop ("# GET KEY requests received"),
908  1,
909  GNUNET_NO);
910  if (GNUNET_YES !=
912  &msg->key))
913  {
914  /* don't bother database... */
916  "Empty result set for GET request for `%s' (bloomfilter).\n",
917  GNUNET_h2s (&msg->key));
920  ("# requests filtered by bloomfilter"),
921  1,
922  GNUNET_NO);
923  transmit_item (client,
924  NULL, 0, NULL, 0, 0, 0, 0,
926  0);
928  return;
929  }
930  plugin->api->get_key (plugin->api->cls,
931  GNUNET_ntohll (msg->next_uid),
932  msg->random,
933  &msg->key,
934  ntohl (msg->type),
935  &transmit_item,
936  client);
938 }
939 
940 
947 static void
949  const struct GNUNET_MessageHeader *message)
950 {
951  struct GNUNET_SERVICE_Client *client = cls;
952 
954  "Processing GET_REPLICATION request\n");
956  gettext_noop ("# GET REPLICATION requests received"),
957  1,
958  GNUNET_NO);
959  plugin->api->get_replication (plugin->api->cls,
960  &transmit_item,
961  client);
963 }
964 
965 
972 static void
974  const struct GetZeroAnonymityMessage *msg)
975 {
976  struct GNUNET_SERVICE_Client *client = cls;
977  enum GNUNET_BLOCK_Type type;
978 
979  type = (enum GNUNET_BLOCK_Type) ntohl (msg->type);
980  if (type == GNUNET_BLOCK_TYPE_ANY)
981  {
982  GNUNET_break (0);
984  return;
985  }
987  "Processing GET_ZERO_ANONYMITY request\n");
989  gettext_noop ("# GET ZERO ANONYMITY requests received"),
990  1,
991  GNUNET_NO);
992  plugin->api->get_zero_anonymity (plugin->api->cls,
993  GNUNET_ntohll (msg->next_uid),
994  type,
995  &transmit_item,
996  client);
998 }
999 
1000 
1011 static void
1013  const struct GNUNET_HashCode *key,
1014  uint32_t size,
1015  int status,
1016  const char *msg)
1017 {
1018  struct GNUNET_SERVICE_Client *client = cls;
1019 
1020  if (GNUNET_SYSERR == status)
1021  {
1023  "REMOVE request failed: %s.\n",
1024  msg);
1025  transmit_status (client,
1026  GNUNET_NO,
1027  msg);
1028  return;
1029  }
1030  if (GNUNET_NO == status)
1031  {
1033  "Content not found for REMOVE request.\n");
1034  transmit_status (client,
1035  GNUNET_NO,
1036  _("Content not found"));
1037  return;
1038  }
1040  "Item matches REMOVE request for key `%s'.\n",
1041  GNUNET_h2s (key));
1042  GNUNET_STATISTICS_update (stats,
1043  gettext_noop ("# bytes removed (explicit request)"),
1044  size,
1045  GNUNET_YES);
1047  key);
1048  transmit_status (client,
1049  GNUNET_OK,
1050  NULL);
1051 }
1052 
1053 
1061 static int
1062 check_remove (void *cls,
1063  const struct DataMessage *dm)
1064 {
1065  if (GNUNET_OK != check_data (dm))
1066  {
1067  GNUNET_break (0);
1068  return GNUNET_SYSERR;
1069  }
1070  return GNUNET_OK;
1071 }
1072 
1073 
1081 static void
1082 handle_remove (void *cls,
1083  const struct DataMessage *dm)
1084 {
1085  struct GNUNET_SERVICE_Client *client = cls;
1086 
1087  GNUNET_STATISTICS_update (stats,
1088  gettext_noop ("# REMOVE requests received"),
1089  1, GNUNET_NO);
1091  "Processing REMOVE request for `%s'\n",
1092  GNUNET_h2s (&dm->key));
1093  plugin->api->remove_key (plugin->api->cls,
1094  &dm->key,
1095  ntohl (dm->size),
1096  &dm[1],
1098  client);
1100 }
1101 
1102 
1109 static void
1110 handle_drop (void *cls,
1111  const struct GNUNET_MessageHeader *message)
1112 {
1113  struct GNUNET_SERVICE_Client *client = cls;
1114 
1116  "Processing DROP request\n");
1117  do_drop = GNUNET_YES;
1119 }
1120 
1121 
1130 static void
1132  int delta)
1133 {
1134  if ((delta < 0) && (payload < -delta))
1135  {
1137  _("Datastore payload must have been inaccurate (%lld < %lld). Recomputing it.\n"),
1138  (long long) payload,
1139  (long long) -delta);
1140  plugin->api->estimate_size (plugin->api->cls,
1141  &payload);
1143  _("New payload: %lld\n"),
1144  (long long) payload);
1145  sync_stats ();
1146  return;
1147  }
1148  payload += delta;
1149  last_sync++;
1151  sync_stats ();
1152 }
1153 
1154 
1165 static int
1166 process_stat_in (void *cls,
1167  const char *subsystem,
1168  const char *name,
1169  uint64_t value,
1170  int is_persistent)
1171 {
1174  payload += value;
1176  "Notification from statistics about existing payload (%llu), new payload is %llu\n",
1177  (unsigned long long) value,
1178  (unsigned long long) payload);
1179  return GNUNET_OK;
1180 }
1181 
1182 
1186 static struct DatastorePlugin *
1188 {
1189  struct DatastorePlugin *ret;
1190  char *libname;
1191 
1192  ret = GNUNET_new (struct DatastorePlugin);
1193  ret->env.cfg = cfg;
1195  ret->env.cls = NULL;
1197  _("Loading `%s' datastore plugin\n"),
1198  plugin_name);
1199  GNUNET_asprintf (&libname,
1200  "libgnunet_plugin_datastore_%s",
1201  plugin_name);
1203  ret->lib_name = libname;
1204  ret->api = GNUNET_PLUGIN_load (libname,
1205  &ret->env);
1206  if (NULL == ret->api)
1207  {
1209  _("Failed to load datastore plugin for `%s'\n"),
1210  plugin_name);
1211  GNUNET_free (ret->short_name);
1212  GNUNET_free (libname);
1213  GNUNET_free (ret);
1214  return NULL;
1215  }
1216  return ret;
1217 }
1218 
1219 
1226 static void
1228 {
1230  "Datastore service is unloading plugin...\n");
1231  GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
1232  GNUNET_free (plug->lib_name);
1233  GNUNET_free (plug->short_name);
1234  GNUNET_free (plug);
1235 }
1236 
1237 
1241 static void
1243 {
1244  GNUNET_SERVICE_resume (service);
1245  expired_kill_task
1247  &delete_expired,
1248  NULL);
1249 }
1250 
1251 
1259 static void
1261  const struct GNUNET_HashCode *key,
1262  unsigned int count)
1263 {
1264  struct GNUNET_CONTAINER_BloomFilter *bf = cls;
1265 
1266  if (NULL == key)
1267  {
1269  _("Bloomfilter construction complete.\n"));
1270  begin_service ();
1271  return;
1272  }
1273 
1274  while (0 < count--)
1276  key);
1277 }
1278 
1279 
1287 static void
1289  int success)
1290 {
1291  stat_get = NULL;
1292  if (NULL != stat_timeout_task)
1293  {
1294  GNUNET_SCHEDULER_cancel (stat_timeout_task);
1295  stat_timeout_task = NULL;
1296  }
1297  plugin = load_plugin ();
1298  if (NULL == plugin)
1299  {
1301  filter = NULL;
1302  if (NULL != stats)
1303  {
1305  GNUNET_YES);
1306  stats = NULL;
1307  }
1308  return;
1309  }
1310 
1311  if (GNUNET_NO == stats_worked)
1312  {
1314  "Failed to obtain value from statistics service, recomputing it\n");
1315  plugin->api->estimate_size (plugin->api->cls,
1316  &payload);
1318  _("New payload: %lld\n"),
1319  (long long) payload);
1320  }
1321 
1322  if (GNUNET_YES == refresh_bf)
1323  {
1325  _("Rebuilding bloomfilter. Please be patient.\n"));
1326  if (NULL != plugin->api->get_keys)
1327  {
1328  plugin->api->get_keys (plugin->api->cls,
1330  filter);
1331  return;
1332  }
1333  else
1334  {
1336  _("Plugin does not support get_keys function. Please fix!\n"));
1337  }
1338  }
1339  begin_service ();
1340 }
1341 
1342 
1348 static void
1349 stat_timeout (void *cls)
1350 {
1351  stat_timeout_task = NULL;
1352  GNUNET_STATISTICS_get_cancel (stat_get);
1353  process_stat_done (NULL,
1354  GNUNET_NO);
1355 }
1356 
1357 
1361 static void
1362 cleaning_task (void *cls)
1363 {
1365  if (NULL != expired_kill_task)
1366  {
1367  GNUNET_SCHEDULER_cancel (expired_kill_task);
1368  expired_kill_task = NULL;
1369  }
1370  if (GNUNET_YES == do_drop)
1371  {
1373  "Dropping database!\n");
1374  plugin->api->drop (plugin->api->cls);
1375  payload = 0;
1376  last_sync++;
1377  }
1378  if (NULL != plugin)
1379  {
1380  unload_plugin (plugin);
1381  plugin = NULL;
1382  }
1383  if (NULL != filter)
1384  {
1386  filter = NULL;
1387  }
1388  if (NULL != stat_get)
1389  {
1390  GNUNET_STATISTICS_get_cancel (stat_get);
1391  stat_get = NULL;
1392  }
1393  if (NULL != stat_timeout_task)
1394  {
1395  GNUNET_SCHEDULER_cancel (stat_timeout_task);
1396  stat_timeout_task = NULL;
1397  }
1399  plugin_name = NULL;
1400  if (last_sync > 0)
1401  sync_stats ();
1402  if (NULL != stats)
1403  {
1405  GNUNET_YES);
1406  stats = NULL;
1407  }
1409  quota_stat_name = NULL;
1410 }
1411 
1412 
1421 static void *
1423  struct GNUNET_SERVICE_Client *client,
1424  struct GNUNET_MQ_Handle *mq)
1425 {
1426  return client;
1427 }
1428 
1429 
1438 static void
1440  struct GNUNET_SERVICE_Client *client,
1441  void *app_ctx)
1442 {
1443  struct ReservationList *pos;
1444  struct ReservationList *prev;
1445  struct ReservationList *next;
1446 
1447  GNUNET_assert (app_ctx == client);
1448  prev = NULL;
1449  pos = reservations;
1450  while (NULL != pos)
1451  {
1452  next = pos->next;
1453  if (pos->client == client)
1454  {
1455  if (NULL == prev)
1456  reservations = next;
1457  else
1458  prev->next = next;
1460  GNUNET_free (pos);
1461  }
1462  else
1463  {
1464  prev = pos;
1465  }
1466  pos = next;
1467  }
1468  GNUNET_STATISTICS_set (stats,
1469  gettext_noop ("# reserved"),
1470  reserved,
1471  GNUNET_NO);
1472 
1473 }
1474 
1475 
1483 static void
1484 run (void *cls,
1485  const struct GNUNET_CONFIGURATION_Handle *c,
1486  struct GNUNET_SERVICE_Handle *serv)
1487 {
1488  char *fn;
1489  char *pfn;
1490  unsigned int bf_size;
1491 
1492  service = serv;
1493  cfg = c;
1494  if (GNUNET_OK !=
1496  "DATASTORE",
1497  "DATABASE",
1498  &plugin_name))
1499  {
1501  "DATABASE",
1502  "DATASTORE");
1503  return;
1504  }
1506  _("# bytes used in file-sharing datastore `%s'"),
1507  plugin_name);
1508  if (GNUNET_OK !=
1510  "DATASTORE",
1511  "QUOTA",
1512  &quota))
1513  {
1515  "QUOTA",
1516  "DATASTORE");
1517  return;
1518  }
1519  stats = GNUNET_STATISTICS_create ("datastore",
1520  cfg);
1521  GNUNET_STATISTICS_set (stats,
1522  gettext_noop ("# quota"),
1523  quota,
1524  GNUNET_NO);
1525  cache_size = quota / 8; /* Or should we make this an option? */
1526  GNUNET_STATISTICS_set (stats,
1527  gettext_noop ("# cache size"),
1528  cache_size,
1529  GNUNET_NO);
1530  if (quota / (32 * 1024LL) > MAX_BF_SIZE)
1531  bf_size = MAX_BF_SIZE;
1532  else
1533  bf_size = quota / (32 * 1024LL); /* 8 bit per entry, 1 bit per 32 kb in DB */
1534  fn = NULL;
1535  if ((GNUNET_OK !=
1537  "DATASTORE",
1538  "BLOOMFILTER",
1539  &fn)) ||
1541  {
1543  _("Could not use specified filename `%s' for bloomfilter.\n"),
1544  NULL != fn ? fn : "");
1545  GNUNET_free_non_null (fn);
1546  fn = NULL;
1547  }
1548  if (NULL != fn)
1549  {
1550  GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name);
1551  if (GNUNET_YES == GNUNET_DISK_file_test (pfn))
1552  {
1553  filter = GNUNET_CONTAINER_bloomfilter_load (pfn, bf_size, 5); /* approx. 3% false positives at max use */
1554  if (NULL == filter)
1555  {
1556  /* file exists but not valid, remove and try again, but refresh */
1557  if (0 != UNLINK (pfn))
1558  {
1559  /* failed to remove, run without file */
1561  _("Failed to remove bogus bloomfilter file `%s'\n"),
1562  pfn);
1563  GNUNET_free (pfn);
1564  pfn = NULL;
1565  filter = GNUNET_CONTAINER_bloomfilter_load (NULL, bf_size, 5); /* approx. 3% false positives at max use */
1567  }
1568  else
1569  {
1570  /* try again after remove */
1571  filter = GNUNET_CONTAINER_bloomfilter_load (pfn, bf_size, 5); /* approx. 3% false positives at max use */
1573  if (NULL == filter)
1574  {
1575  /* failed yet again, give up on using file */
1577  _("Failed to remove bogus bloomfilter file `%s'\n"),
1578  pfn);
1579  GNUNET_free (pfn);
1580  pfn = NULL;
1581  filter = GNUNET_CONTAINER_bloomfilter_init (NULL, bf_size, 5); /* approx. 3% false positives at max use */
1582  }
1583  }
1584  }
1585  else
1586  {
1587  /* normal case: have an existing valid bf file, no need to refresh */
1589  }
1590  }
1591  else
1592  {
1593  filter = GNUNET_CONTAINER_bloomfilter_load (pfn, bf_size, 5); /* approx. 3% false positives at max use */
1595  }
1596  GNUNET_free (pfn);
1597  }
1598  else
1599  {
1600  filter = GNUNET_CONTAINER_bloomfilter_init (NULL,
1601  bf_size,
1602  5); /* approx. 3% false positives at max use */
1604  }
1605  GNUNET_free_non_null (fn);
1606  if (NULL == filter)
1607  {
1609  _("Failed to initialize bloomfilter.\n"));
1610  if (NULL != stats)
1611  {
1613  GNUNET_YES);
1614  stats = NULL;
1615  }
1616  return;
1617  }
1618  GNUNET_SERVICE_suspend (service);
1619  stat_get =
1620  GNUNET_STATISTICS_get (stats,
1621  "datastore",
1624  &process_stat_in,
1625  NULL);
1626  if (NULL == stat_get)
1627  process_stat_done (NULL,
1628  GNUNET_SYSERR);
1629  else
1630  stat_timeout_task
1632  &stat_timeout,
1633  NULL);
1635  NULL);
1636 }
1637 
1638 
1643 ("datastore",
1645  &run,
1648  NULL,
1649  GNUNET_MQ_hd_fixed_size (reserve,
1651  struct ReserveMessage,
1652  NULL),
1653  GNUNET_MQ_hd_fixed_size (release_reserve,
1655  struct ReleaseReserveMessage,
1656  NULL),
1657  GNUNET_MQ_hd_var_size (put,
1659  struct DataMessage,
1660  NULL),
1663  struct GetMessage,
1664  NULL),
1665  GNUNET_MQ_hd_fixed_size (get_key,
1667  struct GetKeyMessage,
1668  NULL),
1669  GNUNET_MQ_hd_fixed_size (get_replication,
1671  struct GNUNET_MessageHeader,
1672  NULL),
1673  GNUNET_MQ_hd_fixed_size (get_zero_anonymity,
1675  struct GetZeroAnonymityMessage,
1676  NULL),
1677  GNUNET_MQ_hd_var_size (remove,
1679  struct DataMessage,
1680  NULL),
1683  struct GNUNET_MessageHeader,
1684  NULL),
1686 
1687 
1688 /* end of gnunet-service-datastore.c */
static void handle_drop(void *cls, const struct GNUNET_MessageHeader *message)
Handle DROP-message.
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:669
static void add_key_to_bloomfilter(void *cls, const struct GNUNET_HashCode *key, unsigned int count)
Adds a given key to the bloomfilter in cls count times.
#define GNUNET_MESSAGE_TYPE_DATASTORE_STATUS
Message sent by datastore to client informing about status processing a request (in response to RESER...
static struct GNUNET_TIME_Absolute min_expiration
Minimum time that content should have to not be discarded instantly (time stamp of any content that w...
static void handle_get(void *cls, const struct GetMessage *msg)
Handle GNUNET_MESSAGE_TYPE_DATASTORE_GET-message.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
static void handle_put(void *cls, const struct DataMessage *dm)
Handle PUT-message.
GNUNET_DATASTORE_DiskUtilizationChange duc
Function to call on disk utilization change.
PluginGetKeys get_keys
Iterate over all keys in the database.
PluginPut put
Function to store an item in the datastore.
static int cleaning_done
Have we already cleaned up the TCCs and are hence no longer willing (or able) to transmit anything to...
uint32_t random
If true return a random result.
Definition: datastore.h:129
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * expiration
Credential TTL.
static void disk_utilization_change_cb(void *cls, int delta)
Function called by plugins to notify us about a change in their disk utilization. ...
GNUNET_SERVICE_MAIN("datastore", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(reserve, GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE, struct ReserveMessage, NULL), GNUNET_MQ_hd_fixed_size(release_reserve, GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE, struct ReleaseReserveMessage, NULL), GNUNET_MQ_hd_var_size(put, GNUNET_MESSAGE_TYPE_DATASTORE_PUT, struct DataMessage, NULL), GNUNET_MQ_hd_fixed_size(get, GNUNET_MESSAGE_TYPE_DATASTORE_GET, struct GetMessage, NULL), GNUNET_MQ_hd_fixed_size(get_key, GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY, struct GetKeyMessage, NULL), GNUNET_MQ_hd_fixed_size(get_replication, GNUNET_MESSAGE_TYPE_DATASTORE_GET_REPLICATION, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(get_zero_anonymity, GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY, struct GetZeroAnonymityMessage, NULL), GNUNET_MQ_hd_var_size(remove, GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE, struct DataMessage, NULL), GNUNET_MQ_hd_fixed_size(drop, GNUNET_MESSAGE_TYPE_DATASTORE_DROP, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static void manage_space(unsigned long long need)
Manage available disk space by running tasks that will discard content if necessary.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct GNUNET_TIME_AbsoluteNBO expiration
Expiration time (NBO); zero for remove.
Definition: datastore.h:252
uint32_t type
Desired content type (actually an enum GNUNET_BLOCK_Type)
Definition: datastore.h:182
uint32_t entries
Number of items to reserve.
Definition: datastore.h:49
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2481
Any type of block, used as a wildcard when searching.
static int transmit_item(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Function that will transmit the given datastore entry to the client.
Message from datastore service informing client about the current size of the datastore.
Definition: datastore.h:39
static struct GNUNET_SERVICE_Handle * service
Handle to our server.
Handle to a service.
Definition: service.c:116
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1178
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
static int quota_processor(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
An iterator over a set of items stored in the datastore that deletes until we&#39;re happy with respect t...
uint32_t type
Type of the item (NBO), zero for remove, (actually an enum GNUNET_BLOCK_Type)
Definition: datastore.h:219
Our datastore plugin.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
char * lib_name
Name of the library (i.e.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static int check_put(void *cls, const struct DataMessage *dm)
Verify PUT-message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t random
If true return a random result.
Definition: datastore.h:163
#define GNUNET_TIME_UNIT_SECONDS
One second.
#define MAX_STAT_SYNC_LAG
After how many payload-changing operations do we sync our statistics?
uint64_t amount
Number of bytes (still) reserved.
PluginRemoveKey remove_key
Function to remove an item from the database.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
Message from datastore client informing service that the remainder of the reserved bytes can now be r...
Definition: datastore.h:90
static unsigned int replication
static void remove_continuation(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Remove continuation.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
PluginEstimateSize estimate_size
Calculate the current on-disk size of the SQ store.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_REPLICATION
Message sent by datastore client to get random data.
static struct Experiment * e
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
Message to the datastore service asking about specific content.
Definition: datastore.h:109
struct GNUNET_TIME_AbsoluteNBO min_expiration
Minimum expiration time required for content to be stored by the datacache at this time...
Definition: datastore.h:80
Linked list of things we still need to do.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Message to the datastore service asking about zero anonymity content.
Definition: datastore.h:172
#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.
#define GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE
Message sent by datastore client on join.
uint64_t next_uid
UID at which to start the search.
Definition: datastore.h:158
static int do_drop
Should the database be dropped on exit?
#define GNUNET_MESSAGE_TYPE_DATASTORE_PUT
Message sent by datastore client to store data.
static char * quota_stat_name
Name under which we store current space consumption.
static int check_remove(void *cls, const struct DataMessage *dm)
Verify REMOVE-message.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void sync_stats()
Synchronize our utilization statistics with the statistics service.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int check_data(const struct DataMessage *dm)
Check that the given message is a valid data message.
#define UNLINK(f)
Definition: plibc.h:666
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:258
Handle to a client that is connected to a service.
Definition: service.c:249
PluginGetRandom get_replication
Function to get a random item with high replication score from the database, lowering the item&#39;s repl...
#define GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE
Message sent by datastore client on join.
#define MAX_EXPIRE_DELAY
How long are we at most keeping "expired" content past the expiration date in the database...
PluginDrop drop
Delete the database.
structs for communication between datastore service and API
static struct DatastorePlugin * load_plugin()
Load the datastore plugin.
static void unload_plugin(struct DatastorePlugin *plug)
Function called when the service shuts down.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
int32_t rid
Reservation identifier.
#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
static struct GNUNET_STATISTICS_GetHandle * stat_get
Handle for pending get request.
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_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1200
static int process_stat_in(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
#define GNUNET_MESSAGE_TYPE_DATASTORE_DROP
Message sent by datastore client to drop the database.
#define GNUNET_memcpy(dst, src, n)
static void handle_get_replication(void *cls, const struct GNUNET_MessageHeader *message)
Handle GET_REPLICATION-message.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_bloomfilter_remove(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Remove an element from the filter.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static char * fn
Filename of the unique file.
Message to the datastore service asking about specific content.
Definition: datastore.h:143
uint32_t type
Desired content type.
Definition: datastore.h:119
static struct ReservationList * reservations
Linked list of space reservations made by clients.
PluginGetRandom get_expiration
Function to get a random expired item or, if none are expired, either the oldest entry or one with a ...
struct ListEntry * entries
List of peers in the list.
static void process_stat_done(void *cls, int success)
We finished receiving the statistic.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
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:727
uint16_t status
See PRISM_STATUS_*-constants.
char * short_name
Short name for the plugin (i.e.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_load(const char *filename, size_t size, unsigned int k)
Load a Bloom filter from a file.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don&#39;t have the content.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.
static struct GNUNET_SCHEDULER_Task * expired_kill_task
Identity of the task that is used to delete expired content.
int GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
#define GNUNET_DATASTORE_ENTRY_OVERHEAD
How many bytes of overhead will we assume per entry in any DB (for reservations)? ...
uint32_t type
Desired content type.
Definition: datastore.h:153
#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END
Message sent by datastore to client signaling end of matching data.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
uint32_t replication
Desired replication level.
Definition: datastore.h:234
Run when otherwise idle.
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.
uint32_t rid
Reservation ID to use; use zero for none.
Definition: datastore.h:209
struct GNUNET_DATASTORE_PluginFunctions * api
API of the transport as returned by the plugin&#39;s initialization function.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
static void stat_timeout(void *cls)
Fetching stats took to long, run without.
struct ReservationList * next
This is a linked list.
struct GNUNET_DATASTORE_PluginEnvironment env
Environment this transport service is using for this plugin.
Message transmitting content from or to the datastore service.
Definition: datastore.h:196
struct GNUNET_HashCode key
Desired key.
Definition: datastore.h:134
static void handle_reserve(void *cls, const struct ReserveMessage *msg)
Handle RESERVE-message.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
static int stats_worked
Did we get an answer from statistics?
uint32_t size
Number of bytes in the item (NBO).
Definition: datastore.h:214
static unsigned int last_sync
Number of updates that were made to the payload value since we last synchronized it with the statisti...
uint32_t anonymity
Desired anonymity level (NBO), zero for remove.
Definition: datastore.h:229
static int refresh_bf
Should we refresh the BF when the DB is loaded?
static void handle_get_key(void *cls, const struct GetKeyMessage *msg)
Handle GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY-message.
const char * name
static void handle_release_reserve(void *cls, const struct ReleaseReserveMessage *msg)
Handle RELEASE_RESERVE-message.
uint64_t entries
Number of items (still) reserved.
static unsigned long long payload
How much data are we currently storing in the database?
int32_t rid
Reservation id.
Definition: datastore.h:100
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
void * cls
Closure to use for all of the following callbacks (except "next_request").
static int expired_processor(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Iterate over the expired items stored in the datastore.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_MessageHeader header
Type is either GNUNET_MESSAGE_TYPE_DATASTORE_PUT, GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE or GNUNET_MESS...
Definition: datastore.h:204
static unsigned long long quota
How much space are we allowed to use?
static struct DatastorePlugin * plugin
Our datastore plugin (NULL if not available).
static void cleaning_task(void *cls)
Task run during shutdown.
Handle to a message queue.
Definition: mq.c:85
static unsigned long long cache_size
How much space are we using for the cache? (space available for insertions that will be instantly rec...
uint64_t next_uid
UID at which to start the search.
Definition: datastore.h:187
uint64_t uid
Unique ID for the content (can be used for UPDATE); can be zero for remove (which indicates that the ...
Definition: datastore.h:247
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY
Message sent by datastore client to get random data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY
Message sent by datastore client to get data by key.
struct GNUNET_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *serv)
Process datastore requests.
configuration data
Definition: configuration.c:85
struct GNUNET_HashCode key
Key under which the item can be found.
Definition: datastore.h:257
uint32_t priority
Priority of the item (NBO), zero for remove.
Definition: datastore.h:224
static void put_continuation(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Put continuation.
static void begin_service()
Initialization complete, start operating the service.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
Message from datastore service informing client about the success or failure of a requested operation...
Definition: datastore.h:64
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define MAX_BF_SIZE
Limit size of bloom filter to 2 GB.
static void handle_remove(void *cls, const struct DataMessage *dm)
Handle REMOVE-message.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
static unsigned int anonymity
int32_t status
Status code, -1 for errors.
Definition: datastore.h:74
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute end)
Compute the time difference between the given start and end times.
Definition: time.c:353
#define MIN_EXPIRE_DELAY
How fast are we allowed to query the database for deleting expired content? (1 item per second)...
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:210
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE
Message sent by datastore client to remove data.
static void transmit_status(struct GNUNET_SERVICE_Client *client, int code, const char *msg)
Transmit a status code to the client.
uint64_t next_uid
UID at which to start the search.
Definition: datastore.h:124
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET
Message sent by datastore client to get data.
static unsigned long long reserved
How much space have we currently reserved?
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:792
struct GNUNET_SERVICE_Client * client
Client that made the reservation.
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2468
PluginGetKey get_key
Get a particular datum matching a given hash from the datastore.
static void delete_expired(void *cls)
Task that is used to remove expired entries from the datastore.
uint32_t data
The data value.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static char * plugin_name
Name of our plugin.
#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA
Message sent by datastore to client providing requested data (in response to GET or GET_RANDOM reques...
Linked list of active reservations.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_SCHEDULER_Task * stat_timeout_task
Task to timeout stat GET.
static void handle_get_zero_anonymity(void *cls, const struct GetZeroAnonymityMessage *msg)
Handle GET_ZERO_ANONYMITY-message.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
uint64_t amount
Number of bytes to reserve.
Definition: datastore.h:54