GNUnet  0.11.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 \
49  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
50 
55 #define MIN_EXPIRE_DELAY \
56  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
57 
61 static char *quota_stat_name;
62 
67 
72 #define MAX_STAT_SYNC_LAG 50
73 
74 
79 {
85 
89  char *short_name;
90 
94  char *lib_name;
95 
101 };
102 
103 
108 {
113 
118 
122  uint64_t amount;
123 
127  uint64_t entries;
128 
132  int32_t rid;
133 };
134 
135 
139 static struct DatastorePlugin *plugin;
140 
145 
150 
154 static char *plugin_name;
155 
159 static const struct GNUNET_CONFIGURATION_Handle *cfg;
160 
165 
172 static unsigned long long cache_size;
173 
177 static unsigned long long reserved;
178 
183 static unsigned long long payload;
184 
190 
198 
202 static unsigned long long quota;
203 
207 static int do_drop;
208 
212 static int refresh_bf;
213 
219 static unsigned int last_sync;
220 
224 static int stats_worked;
225 
226 
231 static void
233 {
236  "# utilization by current datastore",
237  payload,
238  GNUNET_NO);
239  last_sync = 0;
240 }
241 
242 
247 static int cleaning_done;
248 
253 
258 
267 static void
268 delete_expired (void *cls);
269 
270 
292 static int
293 expired_processor (void *cls,
294  const struct GNUNET_HashCode *key,
295  uint32_t size,
296  const void *data,
297  enum GNUNET_BLOCK_Type type,
298  uint32_t priority,
299  uint32_t anonymity,
300  uint32_t replication,
302  uint64_t uid)
303 {
304  struct GNUNET_TIME_Absolute now;
305 
306  if (NULL == key)
307  {
312  NULL);
313  return GNUNET_SYSERR;
314  }
315  now = GNUNET_TIME_absolute_get ();
316  if (expiration.abs_value_us > now.abs_value_us)
317  {
318  /* finished processing */
323  NULL);
324  return GNUNET_SYSERR;
325  }
327  "Deleting content `%s' of type %u that expired %s ago\n",
328  GNUNET_h2s (key),
329  type,
332  GNUNET_YES));
333  min_expiration = now;
335  gettext_noop ("# bytes expired"),
336  size,
337  GNUNET_YES);
343  NULL);
344  return GNUNET_NO;
345 }
346 
347 
356 static void
357 delete_expired (void *cls)
358 {
359  expired_kill_task = NULL;
361 }
362 
363 
383 static int
384 quota_processor (void *cls,
385  const struct GNUNET_HashCode *key,
386  uint32_t size,
387  const void *data,
388  enum GNUNET_BLOCK_Type type,
389  uint32_t priority,
390  uint32_t anonymity,
391  uint32_t replication,
393  uint64_t uid)
394 {
395  unsigned long long *need = cls;
396 
397  if (NULL == key)
398  return GNUNET_SYSERR;
399  GNUNET_log (
401  "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",
402  (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD),
403  (unsigned int) priority,
404  GNUNET_h2s (key),
405  type,
407  expiration),
408  GNUNET_YES),
409  *need);
411  *need = 0;
412  else
414  if (priority > 0)
416  else
419  gettext_noop ("# bytes purged (low-priority)"),
420  size,
421  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;
452  }
453 }
454 
455 
463 static void
465  int code,
466  const char *msg)
467 {
468  struct GNUNET_MQ_Envelope *env;
469  struct StatusMessage *sm;
470  size_t slen;
471 
473  "Transmitting `%s' message with value %d and message `%s'\n",
474  "STATUS",
475  code,
476  msg != NULL ? msg : "(none)");
477  slen = (msg == NULL) ? 0 : strlen (msg) + 1;
479  sm->status = htonl (code);
481  GNUNET_memcpy (&sm[1], msg, slen);
483 }
484 
485 
504 static int
505 transmit_item (void *cls,
506  const struct GNUNET_HashCode *key,
507  uint32_t size,
508  const void *data,
509  enum GNUNET_BLOCK_Type type,
510  uint32_t priority,
511  uint32_t anonymity,
512  uint32_t replication,
514  uint64_t uid)
515 {
516  struct GNUNET_SERVICE_Client *client = cls;
517  struct GNUNET_MQ_Envelope *env;
518  struct GNUNET_MessageHeader *end;
519  struct DataMessage *dm;
520 
521  if (NULL == key)
522  {
523  /* transmit 'DATA_END' */
524  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting DATA_END message\n");
527  return GNUNET_OK;
528  }
531  dm->rid = htonl (0);
532  dm->size = htonl (size);
533  dm->type = htonl (type);
534  dm->priority = htonl (priority);
535  dm->anonymity = htonl (anonymity);
536  dm->replication = htonl (replication);
538  dm->uid = GNUNET_htonll (uid);
539  dm->key = *key;
540  GNUNET_memcpy (&dm[1], data, size);
541  GNUNET_log (
543  "Transmitting DATA message for `%s' of type %u with expiration %s (in: %s)\n",
544  GNUNET_h2s (key),
545  type,
548  expiration),
549  GNUNET_YES));
551  gettext_noop ("# results found"),
552  1,
553  GNUNET_NO);
555  return GNUNET_OK;
556 }
557 
558 
565 static void
566 handle_reserve (void *cls, const struct ReserveMessage *msg)
567 {
571  static int reservation_gen;
572  struct GNUNET_SERVICE_Client *client = cls;
573  struct ReservationList *e;
574  unsigned long long used;
575  unsigned long long req;
576  uint64_t amount;
577  uint32_t entries;
578 
579  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing RESERVE request\n");
580  amount = GNUNET_ntohll (msg->amount);
581  entries = ntohl (msg->entries);
582  used = payload + reserved;
583  req =
584  amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries;
585  if (used + req > quota)
586  {
587  if (quota < used)
588  used =
589  quota; /* cheat a bit for error message (to avoid negative numbers) */
590  GNUNET_log (
592  _ (
593  "Insufficient space (%llu bytes are available) to satisfy RESERVE request for %llu bytes\n"),
594  quota - used,
595  req);
596  if (cache_size < req)
597  {
598  /* TODO: document this in the FAQ; essentially, if this
599  * message happens, the insertion request could be blocked
600  * by less-important content from migration because it is
601  * larger than 1/8th of the overall available space, and
602  * we only reserve 1/8th for "fresh" insertions */GNUNET_log (
604  _ (
605  "The requested amount (%llu bytes) is larger than the cache size (%llu bytes)\n"),
606  req,
607  cache_size);
609  0,
610  gettext_noop (
611  "Insufficient space to satisfy request and "
612  "requested amount is larger than cache size"));
613  }
614  else
615  {
617  0,
618  gettext_noop ("Insufficient space to satisfy request"));
619  }
621  return;
622  }
623  reserved += req;
625  gettext_noop ("# reserved"),
626  reserved,
627  GNUNET_NO);
628  e = GNUNET_new (struct ReservationList);
629  e->next = reservations;
630  reservations = e;
631  e->client = client;
632  e->amount = amount;
633  e->entries = entries;
634  e->rid = ++reservation_gen;
635  if (reservation_gen < 0)
636  reservation_gen = 0; /* wrap around */
637  transmit_status (client, e->rid, NULL);
639 }
640 
641 
648 static void
650 {
651  struct GNUNET_SERVICE_Client *client = cls;
652  struct ReservationList *pos;
653  struct ReservationList *prev;
654  struct ReservationList *next;
655  int rid = ntohl (msg->rid);
656  unsigned long long rem;
657 
658  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing RELEASE_RESERVE request\n");
659  next = reservations;
660  prev = NULL;
661  while (NULL != (pos = next))
662  {
663  next = pos->next;
664  if (rid == pos->rid)
665  {
666  if (prev == NULL)
667  reservations = next;
668  else
669  prev->next = next;
670  rem =
671  pos->amount
672  + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries;
673  GNUNET_assert (reserved >= rem);
674  reserved -= rem;
676  gettext_noop ("# reserved"),
677  reserved,
678  GNUNET_NO);
680  "Returning %llu remaining reserved bytes to storage pool\n",
681  rem);
682  GNUNET_free (pos);
685  return;
686  }
687  prev = pos;
688  }
689  GNUNET_break (0);
692  gettext_noop ("Could not find matching reservation"));
694 }
695 
696 
703 static int
704 check_data (const struct DataMessage *dm)
705 {
706  uint16_t size;
707  uint32_t dsize;
708 
709  size = ntohs (dm->header.size);
710  dsize = ntohl (dm->size);
711  if (size != dsize + sizeof(struct DataMessage))
712  {
713  GNUNET_break (0);
714  return GNUNET_SYSERR;
715  }
716  return GNUNET_OK;
717 }
718 
719 
730 static void
731 put_continuation (void *cls,
732  const struct GNUNET_HashCode *key,
733  uint32_t size,
734  int status,
735  const char *msg)
736 {
737  struct GNUNET_SERVICE_Client *client = cls;
738 
739  if (GNUNET_OK == status)
740  {
742  gettext_noop ("# bytes stored"),
743  size,
744  GNUNET_YES);
747  "Successfully stored %u bytes under key `%s'\n",
748  size,
749  GNUNET_h2s (key));
750  }
751  transmit_status (client,
753  msg);
754  if (quota - reserved - cache_size < payload)
755  {
757  _ ("Need %llu bytes more space (%llu allowed, using %llu)\n"),
758  (unsigned long long) size + GNUNET_DATASTORE_ENTRY_OVERHEAD,
759  (unsigned long long) (quota - reserved - cache_size),
760  (unsigned long long) payload);
762  }
763 }
764 
765 
773 static int
774 check_put (void *cls, const struct DataMessage *dm)
775 {
776  if (GNUNET_OK != check_data (dm))
777  {
778  GNUNET_break (0);
779  return GNUNET_SYSERR;
780  }
781  return GNUNET_OK;
782 }
783 
784 
791 static void
792 handle_put (void *cls, const struct DataMessage *dm)
793 {
794  struct GNUNET_SERVICE_Client *client = cls;
795  int rid;
796  struct ReservationList *pos;
797  uint32_t size;
798 
800  "Processing PUT request for `%s' of type %u\n",
801  GNUNET_h2s (&dm->key),
802  (uint32_t) ntohl (dm->type));
803  rid = ntohl (dm->rid);
804  size = ntohl (dm->size);
805  if (rid > 0)
806  {
807  pos = reservations;
808  while ((NULL != pos) && (rid != pos->rid))
809  pos = pos->next;
810  GNUNET_break (pos != NULL);
811  if (NULL != pos)
812  {
813  GNUNET_break (pos->entries > 0);
814  GNUNET_break (pos->amount >= size);
815  pos->entries--;
816  pos->amount -= size;
819  gettext_noop ("# reserved"),
820  reserved,
821  GNUNET_NO);
822  }
823  }
824  bool absent =
826  plugin->api->put (plugin->api->cls,
827  &dm->key,
828  absent,
829  ntohl (dm->size),
830  &dm[1],
831  ntohl (dm->type),
832  ntohl (dm->priority),
833  ntohl (dm->anonymity),
834  ntohl (dm->replication),
837  client);
839 }
840 
841 
848 static void
849 handle_get (void *cls, const struct GetMessage *msg)
850 {
851  struct GNUNET_SERVICE_Client *client = cls;
852 
854  "Processing GET request of type %u\n",
855  (uint32_t) ntohl (msg->type));
857  gettext_noop ("# GET requests received"),
858  1,
859  GNUNET_NO);
861  GNUNET_ntohll (msg->next_uid),
862  msg->random,
863  NULL,
864  ntohl (msg->type),
865  &transmit_item,
866  client);
868 }
869 
870 
877 static void
878 handle_get_key (void *cls, const struct GetKeyMessage *msg)
879 {
880  struct GNUNET_SERVICE_Client *client = cls;
881 
883  "Processing GET request for `%s' of type %u\n",
884  GNUNET_h2s (&msg->key),
885  (uint32_t) ntohl (msg->type));
887  gettext_noop ("# GET KEY requests received"),
888  1,
889  GNUNET_NO);
891  {
892  /* don't bother database... */
894  "Empty result set for GET request for `%s' (bloomfilter).\n",
895  GNUNET_h2s (&msg->key));
897  gettext_noop (
898  "# requests filtered by bloomfilter"),
899  1,
900  GNUNET_NO);
901  transmit_item (client,
902  NULL,
903  0,
904  NULL,
905  0,
906  0,
907  0,
908  0,
910  0);
912  return;
913  }
915  GNUNET_ntohll (msg->next_uid),
916  msg->random,
917  &msg->key,
918  ntohl (msg->type),
919  &transmit_item,
920  client);
922 }
923 
924 
931 static void
932 handle_get_replication (void *cls, const struct GNUNET_MessageHeader *message)
933 {
934  struct GNUNET_SERVICE_Client *client = cls;
935 
936  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing GET_REPLICATION request\n");
938  gettext_noop (
939  "# GET REPLICATION requests received"),
940  1,
941  GNUNET_NO);
944 }
945 
946 
953 static void
955 {
956  struct GNUNET_SERVICE_Client *client = cls;
957  enum GNUNET_BLOCK_Type type;
958 
959  type = (enum GNUNET_BLOCK_Type) ntohl (msg->type);
961  {
962  GNUNET_break (0);
964  return;
965  }
967  "Processing GET_ZERO_ANONYMITY request\n");
969  gettext_noop (
970  "# GET ZERO ANONYMITY requests received"),
971  1,
972  GNUNET_NO);
974  GNUNET_ntohll (msg->next_uid),
975  type,
976  &transmit_item,
977  client);
979 }
980 
981 
992 static void
994  const struct GNUNET_HashCode *key,
995  uint32_t size,
996  int status,
997  const char *msg)
998 {
999  struct GNUNET_SERVICE_Client *client = cls;
1000 
1001  if (GNUNET_SYSERR == status)
1002  {
1003  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "REMOVE request failed: %s.\n", msg);
1004  transmit_status (client, GNUNET_NO, msg);
1005  return;
1006  }
1007  if (GNUNET_NO == status)
1008  {
1010  "Content not found for REMOVE request.\n");
1011  transmit_status (client, GNUNET_NO, _ ("Content not found"));
1012  return;
1013  }
1015  "Item matches REMOVE request for key `%s'.\n",
1016  GNUNET_h2s (key));
1018  gettext_noop ("# bytes removed (explicit request)"),
1019  size,
1020  GNUNET_YES);
1022  transmit_status (client, GNUNET_OK, NULL);
1023 }
1024 
1025 
1033 static int
1034 check_remove (void *cls, const struct DataMessage *dm)
1035 {
1036  if (GNUNET_OK != check_data (dm))
1037  {
1038  GNUNET_break (0);
1039  return GNUNET_SYSERR;
1040  }
1041  return GNUNET_OK;
1042 }
1043 
1044 
1052 static void
1053 handle_remove (void *cls, const struct DataMessage *dm)
1054 {
1055  struct GNUNET_SERVICE_Client *client = cls;
1056 
1058  gettext_noop ("# REMOVE requests received"),
1059  1,
1060  GNUNET_NO);
1062  "Processing REMOVE request for `%s'\n",
1063  GNUNET_h2s (&dm->key));
1065  &dm->key,
1066  ntohl (dm->size),
1067  &dm[1],
1069  client);
1071 }
1072 
1073 
1080 static void
1081 handle_drop (void *cls, const struct GNUNET_MessageHeader *message)
1082 {
1083  struct GNUNET_SERVICE_Client *client = cls;
1084 
1085  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing DROP request\n");
1086  do_drop = GNUNET_YES;
1088 }
1089 
1090 
1099 static void
1101 {
1102  if ((delta < 0) && (payload < -delta))
1103  {
1104  GNUNET_log (
1106  _ (
1107  "Datastore payload must have been inaccurate (%lld < %lld). Recomputing it.\n"),
1108  (long long) payload,
1109  (long long) -delta);
1112  _ ("New payload: %lld\n"),
1113  (long long) payload);
1114  sync_stats ();
1115  return;
1116  }
1117  payload += delta;
1118  last_sync++;
1120  sync_stats ();
1121 }
1122 
1123 
1134 static int
1135 process_stat_in (void *cls,
1136  const char *subsystem,
1137  const char *name,
1138  uint64_t value,
1139  int is_persistent)
1140 {
1143  payload += value;
1144  GNUNET_log (
1146  "Notification from statistics about existing payload (%llu), new payload is %llu\n",
1147  (unsigned long long) value,
1148  (unsigned long long) payload);
1149  return GNUNET_OK;
1150 }
1151 
1152 
1156 static struct DatastorePlugin *
1158 {
1159  struct DatastorePlugin *ret;
1160  char *libname;
1161 
1162  ret = GNUNET_new (struct DatastorePlugin);
1163  ret->env.cfg = cfg;
1164  ret->env.duc = &disk_utilization_change_cb;
1165  ret->env.cls = NULL;
1167  _ ("Loading `%s' datastore plugin\n"),
1168  plugin_name);
1169  GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", plugin_name);
1170  ret->short_name = GNUNET_strdup (plugin_name);
1171  ret->lib_name = libname;
1172  ret->api = GNUNET_PLUGIN_load (libname, &ret->env);
1173  if (NULL == ret->api)
1174  {
1176  _ ("Failed to load datastore plugin for `%s'\n"),
1177  plugin_name);
1178  GNUNET_free (ret->short_name);
1179  GNUNET_free (libname);
1180  GNUNET_free (ret);
1181  return NULL;
1182  }
1183  return ret;
1184 }
1185 
1186 
1193 static void
1195 {
1197  "Datastore service is unloading plugin...\n");
1198  GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
1199  GNUNET_free (plug->lib_name);
1200  GNUNET_free (plug->short_name);
1201  GNUNET_free (plug);
1202 }
1203 
1204 
1208 static void
1210 {
1214  &delete_expired,
1215  NULL);
1216 }
1217 
1218 
1226 static void
1228  const struct GNUNET_HashCode *key,
1229  unsigned int count)
1230 {
1231  struct GNUNET_CONTAINER_BloomFilter *bf = cls;
1232 
1233  if (NULL == key)
1234  {
1236  _ ("Bloomfilter construction complete.\n"));
1237  begin_service ();
1238  return;
1239  }
1240 
1241  while (0 < count--)
1243 }
1244 
1245 
1253 static void
1254 process_stat_done (void *cls, int success)
1255 {
1256  stat_get = NULL;
1257  if (NULL != stat_timeout_task)
1258  {
1260  stat_timeout_task = NULL;
1261  }
1262  plugin = load_plugin ();
1263  if (NULL == plugin)
1264  {
1266  filter = NULL;
1267  if (NULL != stats)
1268  {
1270  stats = NULL;
1271  }
1272  return;
1273  }
1274 
1275  if (GNUNET_NO == stats_worked)
1276  {
1278  "Failed to obtain value from statistics service, recomputing it\n");
1281  _ ("New payload: %lld\n"),
1282  (long long) payload);
1283  }
1284 
1285  if (GNUNET_YES == refresh_bf)
1286  {
1288  _ ("Rebuilding bloomfilter. Please be patient.\n"));
1289  if (NULL != plugin->api->get_keys)
1290  {
1292  return;
1293  }
1294  else
1295  {
1297  _ (
1298  "Plugin does not support get_keys function. Please fix!\n"));
1299  }
1300  }
1301  begin_service ();
1302 }
1303 
1304 
1310 static void
1311 stat_timeout (void *cls)
1312 {
1313  stat_timeout_task = NULL;
1315  process_stat_done (NULL, GNUNET_NO);
1316 }
1317 
1318 
1322 static void
1323 cleaning_task (void *cls)
1324 {
1326  if (NULL != expired_kill_task)
1327  {
1329  expired_kill_task = NULL;
1330  }
1331  if (GNUNET_YES == do_drop)
1332  {
1333  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropping database!\n");
1334  plugin->api->drop (plugin->api->cls);
1335  payload = 0;
1336  last_sync++;
1337  }
1338  if (NULL != plugin)
1339  {
1341  plugin = NULL;
1342  }
1343  if (NULL != filter)
1344  {
1346  filter = NULL;
1347  }
1348  if (NULL != stat_get)
1349  {
1351  stat_get = NULL;
1352  }
1353  if (NULL != stat_timeout_task)
1354  {
1356  stat_timeout_task = NULL;
1357  }
1359  plugin_name = NULL;
1360  if (last_sync > 0)
1361  sync_stats ();
1362  if (NULL != stats)
1363  {
1365  stats = NULL;
1366  }
1368  quota_stat_name = NULL;
1369 }
1370 
1371 
1380 static void *
1382  struct GNUNET_SERVICE_Client *client,
1383  struct GNUNET_MQ_Handle *mq)
1384 {
1385  return client;
1386 }
1387 
1388 
1397 static void
1399  struct GNUNET_SERVICE_Client *client,
1400  void *app_ctx)
1401 {
1402  struct ReservationList *pos;
1403  struct ReservationList *prev;
1404  struct ReservationList *next;
1405 
1406  GNUNET_assert (app_ctx == client);
1407  prev = NULL;
1408  pos = reservations;
1409  while (NULL != pos)
1410  {
1411  next = pos->next;
1412  if (pos->client == client)
1413  {
1414  if (NULL == prev)
1415  reservations = next;
1416  else
1417  prev->next = next;
1419  GNUNET_free (pos);
1420  }
1421  else
1422  {
1423  prev = pos;
1424  }
1425  pos = next;
1426  }
1428  gettext_noop ("# reserved"),
1429  reserved,
1430  GNUNET_NO);
1431 }
1432 
1433 
1441 static void
1442 run (void *cls,
1443  const struct GNUNET_CONFIGURATION_Handle *c,
1444  struct GNUNET_SERVICE_Handle *serv)
1445 {
1446  char *fn;
1447  char *pfn;
1448  unsigned int bf_size;
1449 
1450  service = serv;
1451  cfg = c;
1453  "DATASTORE",
1454  "DATABASE",
1455  &plugin_name))
1456  {
1458  "DATABASE",
1459  "DATASTORE");
1460  return;
1461  }
1463  _ ("# bytes used in file-sharing datastore `%s'"),
1464  plugin_name);
1465  if (GNUNET_OK !=
1466  GNUNET_CONFIGURATION_get_value_size (cfg, "DATASTORE", "QUOTA", &quota))
1467  {
1468  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "QUOTA", "DATASTORE");
1469  return;
1470  }
1471  stats = GNUNET_STATISTICS_create ("datastore", cfg);
1473  cache_size = quota / 8; /* Or should we make this an option? */
1475  gettext_noop ("# cache size"),
1476  cache_size,
1477  GNUNET_NO);
1478  if (quota / (32 * 1024LL) > MAX_BF_SIZE)
1479  bf_size = MAX_BF_SIZE;
1480  else
1481  bf_size =
1482  quota / (32 * 1024LL); /* 8 bit per entry, 1 bit per 32 kb in DB */
1483  fn = NULL;
1485  "DATASTORE",
1486  "BLOOMFILTER",
1487  &fn)) ||
1489  {
1491  _ ("Could not use specified filename `%s' for bloomfilter.\n"),
1492  NULL != fn ? fn : "");
1493  GNUNET_free (fn);
1494  fn = NULL;
1495  }
1496  if (NULL != fn)
1497  {
1498  GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name);
1499  if (GNUNET_YES == GNUNET_DISK_file_test (pfn))
1500  {
1501  filter =
1503  bf_size,
1504  5); /* approx. 3% false positives at max use */
1505  if (NULL == filter)
1506  {
1507  /* file exists but not valid, remove and try again, but refresh */
1508  if (0 != unlink (pfn))
1509  {
1510  /* failed to remove, run without file */
1512  _ ("Failed to remove bogus bloomfilter file `%s'\n"),
1513  pfn);
1514  GNUNET_free (pfn);
1515  pfn = NULL;
1517  NULL,
1518  bf_size,
1519  5); /* approx. 3% false positives at max use */
1521  }
1522  else
1523  {
1524  /* try again after remove */
1526  pfn,
1527  bf_size,
1528  5); /* approx. 3% false positives at max use */
1530  if (NULL == filter)
1531  {
1532  /* failed yet again, give up on using file */
1534  _ ("Failed to remove bogus bloomfilter file `%s'\n"),
1535  pfn);
1536  GNUNET_free (pfn);
1537  pfn = NULL;
1539  NULL,
1540  bf_size,
1541  5); /* approx. 3% false positives at max use */
1542  }
1543  }
1544  }
1545  else
1546  {
1547  /* normal case: have an existing valid bf file, no need to refresh */
1549  }
1550  }
1551  else
1552  {
1553  filter =
1555  bf_size,
1556  5); /* approx. 3% false positives at max use */
1558  }
1559  GNUNET_free (pfn);
1560  }
1561  else
1562  {
1563  filter =
1565  bf_size,
1566  5); /* approx. 3% false positives at max use */
1568  }
1569  GNUNET_free (fn);
1570  if (NULL == filter)
1571  {
1573  _ ("Failed to initialize bloomfilter.\n"));
1574  if (NULL != stats)
1575  {
1577  stats = NULL;
1578  }
1579  return;
1580  }
1583  "datastore",
1586  &process_stat_in,
1587  NULL);
1588  if (NULL == stat_get)
1590  else
1592  &stat_timeout,
1593  NULL);
1595 }
1596 
1597 
1602  "datastore",
1604  &run,
1607  NULL,
1608  GNUNET_MQ_hd_fixed_size (reserve,
1610  struct ReserveMessage,
1611  NULL),
1612  GNUNET_MQ_hd_fixed_size (release_reserve,
1614  struct ReleaseReserveMessage,
1615  NULL),
1616  GNUNET_MQ_hd_var_size (put,
1618  struct DataMessage,
1619  NULL),
1622  struct GetMessage,
1623  NULL),
1626  struct GetKeyMessage,
1627  NULL),
1628  GNUNET_MQ_hd_fixed_size (get_replication,
1630  struct GNUNET_MessageHeader,
1631  NULL),
1632  GNUNET_MQ_hd_fixed_size (get_zero_anonymity,
1634  struct GetZeroAnonymityMessage,
1635  NULL),
1636  GNUNET_MQ_hd_var_size (remove,
1638  struct DataMessage,
1639  NULL),
1642  struct GNUNET_MessageHeader,
1643  NULL),
1645 
1646 
1647 /* end of gnunet-service-datastore.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
structs for communication between datastore service and API
#define gettext_noop(String)
Definition: gettext.h:69
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static struct Experiment * e
static unsigned int replication
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int anonymity
uint32_t data
The data value.
uint16_t status
See PRISM_STATUS_*-constants.
static char * value
Value of the record to add/remove.
static int check_put(void *cls, const struct DataMessage *dm)
Verify PUT-message.
static struct GNUNET_STATISTICS_GetHandle * stat_get
Handle for pending get request.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *serv)
Process datastore requests.
static void stat_timeout(void *cls)
Fetching stats took to long, run without.
static void handle_drop(void *cls, const struct GNUNET_MessageHeader *message)
Handle DROP-message.
static void cleaning_task(void *cls)
Task run during shutdown.
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.
static char * plugin_name
Name of our plugin.
static struct DatastorePlugin * load_plugin()
Load the datastore plugin.
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.
static struct DatastorePlugin * plugin
Our datastore plugin (NULL if not available).
static int stats_worked
Did we get an answer from statistics?
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_SCHEDULER_Task * stat_timeout_task
Task to timeout stat GET.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
static void delete_expired(void *cls)
Task that is used to remove expired entries from the datastore.
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_remove(void *cls, const struct DataMessage *dm)
Handle REMOVE-message.
static unsigned long long payload
How much data are we currently storing in the database?
static int check_remove(void *cls, const struct DataMessage *dm)
Verify REMOVE-message.
static void handle_reserve(void *cls, const struct ReserveMessage *msg)
Handle RESERVE-message.
#define MAX_BF_SIZE
Limit size of bloom filter to 2 GB.
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.
static void put_continuation(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Put continuation.
static char * quota_stat_name
Name under which we store current space consumption.
static void handle_get_key(void *cls, const struct GetKeyMessage *msg)
Handle GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY-message.
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're happy with respect t...
static void process_stat_done(void *cls, int success)
We finished receiving the statistic.
static void remove_continuation(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Remove continuation.
#define MIN_EXPIRE_DELAY
How fast are we allowed to query the database for deleting expired content? (1 item per second).
static void transmit_status(struct GNUNET_SERVICE_Client *client, int code, const char *msg)
Transmit a status code to the client.
static int check_data(const struct DataMessage *dm)
Check that the given message is a valid data message.
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.
static int do_drop
Should the database be dropped on exit?
static int cleaning_done
Have we already cleaned up the TCCs and are hence no longer willing (or able) to transmit anything to...
static void handle_release_reserve(void *cls, const struct ReleaseReserveMessage *msg)
Handle RELEASE_RESERVE-message.
#define MAX_STAT_SYNC_LAG
After how many payload-changing operations do we sync our statistics?
static void manage_space(unsigned long long need)
Manage available disk space by running tasks that will discard content if necessary.
static struct GNUNET_SCHEDULER_Task * expired_kill_task
Identity of the task that is used to delete expired content.
static void begin_service()
Initialization complete, start operating the service.
static unsigned long long quota
How much space are we allowed to use?
static struct ReservationList * reservations
Linked list of space reservations made by clients.
static unsigned int last_sync
Number of updates that were made to the payload value since we last synchronized it with the statisti...
static void handle_get_replication(void *cls, const struct GNUNET_MessageHeader *message)
Handle GET_REPLICATION-message.
static void handle_get(void *cls, const struct GetMessage *msg)
Handle GNUNET_MESSAGE_TYPE_DATASTORE_GET-message.
static unsigned long long reserved
How much space have we currently reserved?
static void sync_stats()
Synchronize our utilization statistics with the statistics service.
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.
static void handle_put(void *cls, const struct DataMessage *dm)
Handle PUT-message.
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.
static void unload_plugin(struct DatastorePlugin *plug)
Function called when the service shuts down.
#define MAX_EXPIRE_DELAY
How long are we at most keeping "expired" content past the expiration date in the database?
static void disk_utilization_change_cb(void *cls, int delta)
Function called by plugins to notify us about a change in their disk utilization.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
static struct GNUNET_SERVICE_Handle * service
Handle to our server.
static int refresh_bf
Should we refresh the BF when the DB is loaded?
static unsigned long long cache_size
How much space are we using for the cache? (space available for insertions that will be instantly rec...
static void handle_get_zero_anonymity(void *cls, const struct GetZeroAnonymityMessage *msg)
Handle GET_ZERO_ANONYMITY-message.
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
@ GNUNET_SCHEDULER_PRIORITY_IDLE
Run when otherwise idle.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
@ GNUNET_BLOCK_TYPE_ANY
Any type of block, used as a wildcard when searching.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_load(const char *filename, size_t size, unsigned int k)
Load a Bloom filter from a file.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to 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.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_remove(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Remove an element from the filter.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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_DATASTORE_ENTRY_OVERHEAD
How many bytes of overhead will we assume per entry in any DB (for reservations)?
enum GNUNET_GenericReturnValue 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:482
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
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:355
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:269
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:217
#define GNUNET_MESSAGE_TYPE_DATASTORE_DROP
Message sent by datastore client to drop the database.
#define GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE
Message sent by datastore client on join.
#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END
Message sent by datastore to client signaling end of matching data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY
Message sent by datastore client to get data by key.
#define GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE
Message sent by datastore client on join.
#define GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE
Message sent by datastore client to remove data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET
Message sent by datastore client to get data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA
Message sent by datastore to client providing requested data (in response to GET or GET_RANDOM reques...
#define GNUNET_MESSAGE_TYPE_DATASTORE_PUT
Message sent by datastore client to store data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_REPLICATION
Message sent by datastore client to get random data.
#define GNUNET_MESSAGE_TYPE_DATASTORE_STATUS
Message sent by datastore to client informing about status processing a request (in response to RESER...
#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY
Message sent by datastore client to get random data.
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:1199
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:1223
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,...
Definition: scheduler.c:1331
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2183
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2438
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2195
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
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_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
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.
#define GNUNET_TIME_UNIT_SECONDS
One second.
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:232
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:604
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
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:557
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:248
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:464
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
Message transmitting content from or to the datastore service.
Definition: datastore.h:192
uint32_t priority
Priority of the item (NBO), zero for remove.
Definition: datastore.h:219
struct GNUNET_HashCode key
Key under which the item can be found.
Definition: datastore.h:252
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:242
struct GNUNET_TIME_AbsoluteNBO expiration
Expiration time (NBO); zero for remove.
Definition: datastore.h:247
struct GNUNET_MessageHeader header
Type is either GNUNET_MESSAGE_TYPE_DATASTORE_PUT, GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE or GNUNET_MESS...
Definition: datastore.h:199
uint32_t type
Type of the item (NBO), zero for remove, (actually an enum GNUNET_BLOCK_Type)
Definition: datastore.h:214
uint32_t size
Number of bytes in the item (NBO).
Definition: datastore.h:209
uint32_t replication
Desired replication level.
Definition: datastore.h:229
uint32_t anonymity
Desired anonymity level (NBO), zero for remove.
Definition: datastore.h:224
uint32_t rid
Reservation ID to use; use zero for none.
Definition: datastore.h:204
Our datastore plugin.
char * lib_name
Name of the library (e.g.
struct GNUNET_DATASTORE_PluginFunctions * api
API of the transport as returned by the plugin's initialization function.
char * short_name
Short name for the plugin (e.g.
struct GNUNET_DATASTORE_PluginEnvironment env
Environment this transport service is using for this plugin.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
PluginGetKey get_key
Get a particular datum matching a given hash from the datastore.
PluginGetRandom get_expiration
Function to get a random expired item or, if none are expired, either the oldest entry or one with a ...
PluginEstimateSize estimate_size
Calculate the current on-disk size of the SQ store.
PluginGetKeys get_keys
Iterate over all keys in the database.
PluginGetRandom get_replication
Function to get a random item with high replication score from the database, lowering the item's repl...
PluginPut put
Function to store an item in the datastore.
void * cls
Closure to use for all of the following callbacks (except "next_request").
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
PluginDrop drop
Delete the database.
PluginRemoveKey remove_key
Function to remove an item from the database.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
Linked list of things we still need to do.
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Message to the datastore service asking about specific content.
Definition: datastore.h:108
Message to the datastore service asking about specific content.
Definition: datastore.h:141
Message to the datastore service asking about zero anonymity content.
Definition: datastore.h:169
Message from datastore client informing service that the remainder of the reserved bytes can now be r...
Definition: datastore.h:90
Linked list of active reservations.
uint64_t amount
Number of bytes (still) reserved.
struct GNUNET_SERVICE_Client * client
Client that made the reservation.
int32_t rid
Reservation identifier.
uint64_t entries
Number of items (still) reserved.
struct ReservationList * next
This is a linked list.
Message from datastore service informing client about the current size of the datastore.
Definition: datastore.h:40
Message from datastore service informing client about the success or failure of a requested operation...
Definition: datastore.h:65
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
int32_t status
Status code, -1 for errors.
Definition: datastore.h:74
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct ListEntry * entries
List of peers in the list.
static char * get_key(char *line)
Definition: testing.c:1799