GNUnet  0.16.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 */
603  GNUNET_log (
605  _ (
606  "The requested amount (%llu bytes) is larger than the cache size (%llu bytes)\n"),
607  req,
608  cache_size);
610  0,
611  gettext_noop (
612  "Insufficient space to satisfy request and "
613  "requested amount is larger than cache size"));
614  }
615  else
616  {
618  0,
619  gettext_noop ("Insufficient space to satisfy request"));
620  }
622  return;
623  }
624  reserved += req;
626  gettext_noop ("# reserved"),
627  reserved,
628  GNUNET_NO);
629  e = GNUNET_new (struct ReservationList);
630  e->next = reservations;
631  reservations = e;
632  e->client = client;
633  e->amount = amount;
634  e->entries = entries;
635  e->rid = ++reservation_gen;
636  if (reservation_gen < 0)
637  reservation_gen = 0; /* wrap around */
638  transmit_status (client, e->rid, NULL);
640 }
641 
642 
649 static void
651 {
652  struct GNUNET_SERVICE_Client *client = cls;
653  struct ReservationList *pos;
654  struct ReservationList *prev;
655  struct ReservationList *next;
656  int rid = ntohl (msg->rid);
657  unsigned long long rem;
658 
659  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing RELEASE_RESERVE request\n");
660  next = reservations;
661  prev = NULL;
662  while (NULL != (pos = next))
663  {
664  next = pos->next;
665  if (rid == pos->rid)
666  {
667  if (prev == NULL)
668  reservations = next;
669  else
670  prev->next = next;
671  rem =
672  pos->amount
673  + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries;
674  GNUNET_assert (reserved >= rem);
675  reserved -= rem;
677  gettext_noop ("# reserved"),
678  reserved,
679  GNUNET_NO);
681  "Returning %llu remaining reserved bytes to storage pool\n",
682  rem);
683  GNUNET_free (pos);
686  return;
687  }
688  prev = pos;
689  }
690  GNUNET_break (0);
693  gettext_noop ("Could not find matching reservation"));
695 }
696 
697 
704 static int
705 check_data (const struct DataMessage *dm)
706 {
707  uint16_t size;
708  uint32_t dsize;
709 
710  size = ntohs (dm->header.size);
711  dsize = ntohl (dm->size);
712  if (size != dsize + sizeof(struct DataMessage))
713  {
714  GNUNET_break (0);
715  return GNUNET_SYSERR;
716  }
717  return GNUNET_OK;
718 }
719 
720 
731 static void
732 put_continuation (void *cls,
733  const struct GNUNET_HashCode *key,
734  uint32_t size,
735  int status,
736  const char *msg)
737 {
738  struct GNUNET_SERVICE_Client *client = cls;
739 
740  if (GNUNET_OK == status)
741  {
743  gettext_noop ("# bytes stored"),
744  size,
745  GNUNET_YES);
748  "Successfully stored %u bytes under key `%s'\n",
749  size,
750  GNUNET_h2s (key));
751  }
752  transmit_status (client,
754  msg);
755  if (quota - reserved - cache_size < payload)
756  {
758  _ ("Need %llu bytes more space (%llu allowed, using %llu)\n"),
759  (unsigned long long) size + GNUNET_DATASTORE_ENTRY_OVERHEAD,
760  (unsigned long long) (quota - reserved - cache_size),
761  (unsigned long long) payload);
763  }
764 }
765 
766 
774 static int
775 check_put (void *cls, const struct DataMessage *dm)
776 {
777  if (GNUNET_OK != check_data (dm))
778  {
779  GNUNET_break (0);
780  return GNUNET_SYSERR;
781  }
782  return GNUNET_OK;
783 }
784 
785 
792 static void
793 handle_put (void *cls, const struct DataMessage *dm)
794 {
795  struct GNUNET_SERVICE_Client *client = cls;
796  int rid;
797  struct ReservationList *pos;
798  uint32_t size;
799 
801  "Processing PUT request for `%s' of type %u\n",
802  GNUNET_h2s (&dm->key),
803  (uint32_t) ntohl (dm->type));
804  rid = ntohl (dm->rid);
805  size = ntohl (dm->size);
806  if (rid > 0)
807  {
808  pos = reservations;
809  while ((NULL != pos) && (rid != pos->rid))
810  pos = pos->next;
811  GNUNET_break (pos != NULL);
812  if (NULL != pos)
813  {
814  GNUNET_break (pos->entries > 0);
815  GNUNET_break (pos->amount >= size);
816  pos->entries--;
817  pos->amount -= size;
820  gettext_noop ("# reserved"),
821  reserved,
822  GNUNET_NO);
823  }
824  }
825  bool absent =
827  plugin->api->put (plugin->api->cls,
828  &dm->key,
829  absent,
830  ntohl (dm->size),
831  &dm[1],
832  ntohl (dm->type),
833  ntohl (dm->priority),
834  ntohl (dm->anonymity),
835  ntohl (dm->replication),
838  client);
840 }
841 
842 
849 static void
850 handle_get (void *cls, const struct GetMessage *msg)
851 {
852  struct GNUNET_SERVICE_Client *client = cls;
853 
855  "Processing GET request of type %u\n",
856  (uint32_t) ntohl (msg->type));
858  gettext_noop ("# GET requests received"),
859  1,
860  GNUNET_NO);
862  GNUNET_ntohll (msg->next_uid),
863  msg->random,
864  NULL,
865  ntohl (msg->type),
866  &transmit_item,
867  client);
869 }
870 
871 
878 static void
879 handle_get_key (void *cls, const struct GetKeyMessage *msg)
880 {
881  struct GNUNET_SERVICE_Client *client = cls;
882 
884  "Processing GET request for `%s' of type %u\n",
885  GNUNET_h2s (&msg->key),
886  (uint32_t) ntohl (msg->type));
888  gettext_noop ("# GET KEY requests received"),
889  1,
890  GNUNET_NO);
892  {
893  /* don't bother database... */
895  "Empty result set for GET request for `%s' (bloomfilter).\n",
896  GNUNET_h2s (&msg->key));
898  gettext_noop (
899  "# requests filtered by bloomfilter"),
900  1,
901  GNUNET_NO);
902  transmit_item (client,
903  NULL,
904  0,
905  NULL,
906  0,
907  0,
908  0,
909  0,
911  0);
913  return;
914  }
916  GNUNET_ntohll (msg->next_uid),
917  msg->random,
918  &msg->key,
919  ntohl (msg->type),
920  &transmit_item,
921  client);
923 }
924 
925 
932 static void
933 handle_get_replication (void *cls, const struct GNUNET_MessageHeader *message)
934 {
935  struct GNUNET_SERVICE_Client *client = cls;
936 
937  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing GET_REPLICATION request\n");
939  gettext_noop (
940  "# GET REPLICATION requests received"),
941  1,
942  GNUNET_NO);
945 }
946 
947 
954 static void
956 {
957  struct GNUNET_SERVICE_Client *client = cls;
958  enum GNUNET_BLOCK_Type type;
959 
960  type = (enum GNUNET_BLOCK_Type) ntohl (msg->type);
962  {
963  GNUNET_break (0);
965  return;
966  }
968  "Processing GET_ZERO_ANONYMITY request\n");
970  gettext_noop (
971  "# GET ZERO ANONYMITY requests received"),
972  1,
973  GNUNET_NO);
975  GNUNET_ntohll (msg->next_uid),
976  type,
977  &transmit_item,
978  client);
980 }
981 
982 
993 static void
995  const struct GNUNET_HashCode *key,
996  uint32_t size,
997  int status,
998  const char *msg)
999 {
1000  struct GNUNET_SERVICE_Client *client = cls;
1001 
1002  if (GNUNET_SYSERR == status)
1003  {
1004  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "REMOVE request failed: %s.\n", msg);
1005  transmit_status (client, GNUNET_NO, msg);
1006  return;
1007  }
1008  if (GNUNET_NO == status)
1009  {
1011  "Content not found for REMOVE request.\n");
1012  transmit_status (client, GNUNET_NO, _ ("Content not found"));
1013  return;
1014  }
1016  "Item matches REMOVE request for key `%s'.\n",
1017  GNUNET_h2s (key));
1019  gettext_noop ("# bytes removed (explicit request)"),
1020  size,
1021  GNUNET_YES);
1023  transmit_status (client, GNUNET_OK, NULL);
1024 }
1025 
1026 
1034 static int
1035 check_remove (void *cls, const struct DataMessage *dm)
1036 {
1037  if (GNUNET_OK != check_data (dm))
1038  {
1039  GNUNET_break (0);
1040  return GNUNET_SYSERR;
1041  }
1042  return GNUNET_OK;
1043 }
1044 
1045 
1053 static void
1054 handle_remove (void *cls, const struct DataMessage *dm)
1055 {
1056  struct GNUNET_SERVICE_Client *client = cls;
1057 
1059  gettext_noop ("# REMOVE requests received"),
1060  1,
1061  GNUNET_NO);
1063  "Processing REMOVE request for `%s'\n",
1064  GNUNET_h2s (&dm->key));
1066  &dm->key,
1067  ntohl (dm->size),
1068  &dm[1],
1070  client);
1072 }
1073 
1074 
1081 static void
1082 handle_drop (void *cls, const struct GNUNET_MessageHeader *message)
1083 {
1084  struct GNUNET_SERVICE_Client *client = cls;
1085 
1086  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing DROP request\n");
1087  do_drop = GNUNET_YES;
1089 }
1090 
1091 
1100 static void
1102 {
1103  if ((delta < 0) && (payload < -delta))
1104  {
1105  GNUNET_log (
1107  _ (
1108  "Datastore payload must have been inaccurate (%lld < %lld). Recomputing it.\n"),
1109  (long long) payload,
1110  (long long) -delta);
1113  _ ("New payload: %lld\n"),
1114  (long long) payload);
1115  sync_stats ();
1116  return;
1117  }
1118  payload += delta;
1119  last_sync++;
1121  sync_stats ();
1122 }
1123 
1124 
1135 static int
1136 process_stat_in (void *cls,
1137  const char *subsystem,
1138  const char *name,
1139  uint64_t value,
1140  int is_persistent)
1141 {
1144  payload += value;
1145  GNUNET_log (
1147  "Notification from statistics about existing payload (%llu), new payload is %llu\n",
1148  (unsigned long long) value,
1149  (unsigned long long) payload);
1150  return GNUNET_OK;
1151 }
1152 
1153 
1157 static struct DatastorePlugin *
1159 {
1160  struct DatastorePlugin *ret;
1161  char *libname;
1162 
1163  ret = GNUNET_new (struct DatastorePlugin);
1164  ret->env.cfg = cfg;
1165  ret->env.duc = &disk_utilization_change_cb;
1166  ret->env.cls = NULL;
1168  _ ("Loading `%s' datastore plugin\n"),
1169  plugin_name);
1170  GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", plugin_name);
1171  ret->short_name = GNUNET_strdup (plugin_name);
1172  ret->lib_name = libname;
1173  ret->api = GNUNET_PLUGIN_load (libname, &ret->env);
1174  if (NULL == ret->api)
1175  {
1177  _ ("Failed to load datastore plugin for `%s'\n"),
1178  plugin_name);
1179  GNUNET_free (ret->short_name);
1180  GNUNET_free (libname);
1181  GNUNET_free (ret);
1182  return NULL;
1183  }
1184  return ret;
1185 }
1186 
1187 
1194 static void
1196 {
1198  "Datastore service is unloading plugin...\n");
1199  GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
1200  GNUNET_free (plug->lib_name);
1201  GNUNET_free (plug->short_name);
1202  GNUNET_free (plug);
1203 }
1204 
1205 
1209 static void
1211 {
1215  &delete_expired,
1216  NULL);
1217 }
1218 
1219 
1227 static void
1229  const struct GNUNET_HashCode *key,
1230  unsigned int count)
1231 {
1232  struct GNUNET_CONTAINER_BloomFilter *bf = cls;
1233 
1234  if (NULL == key)
1235  {
1237  _ ("Bloomfilter construction complete.\n"));
1238  begin_service ();
1239  return;
1240  }
1241 
1242  while (0 < count--)
1244 }
1245 
1246 
1254 static void
1255 process_stat_done (void *cls, int success)
1256 {
1257  stat_get = NULL;
1258  if (NULL != stat_timeout_task)
1259  {
1261  stat_timeout_task = NULL;
1262  }
1263  plugin = load_plugin ();
1264  if (NULL == plugin)
1265  {
1267  filter = NULL;
1268  if (NULL != stats)
1269  {
1271  stats = NULL;
1272  }
1273  return;
1274  }
1275 
1276  if (GNUNET_NO == stats_worked)
1277  {
1279  "Failed to obtain value from statistics service, recomputing it\n");
1282  _ ("New payload: %lld\n"),
1283  (long long) payload);
1284  }
1285 
1286  if (GNUNET_YES == refresh_bf)
1287  {
1289  _ ("Rebuilding bloomfilter. Please be patient.\n"));
1290  if (NULL != plugin->api->get_keys)
1291  {
1293  return;
1294  }
1295  else
1296  {
1298  _ (
1299  "Plugin does not support get_keys function. Please fix!\n"));
1300  }
1301  }
1302  begin_service ();
1303 }
1304 
1305 
1311 static void
1312 stat_timeout (void *cls)
1313 {
1314  stat_timeout_task = NULL;
1316  process_stat_done (NULL, GNUNET_NO);
1317 }
1318 
1319 
1323 static void
1324 cleaning_task (void *cls)
1325 {
1327  if (NULL != expired_kill_task)
1328  {
1330  expired_kill_task = NULL;
1331  }
1332  if (GNUNET_YES == do_drop)
1333  {
1334  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropping database!\n");
1335  plugin->api->drop (plugin->api->cls);
1336  payload = 0;
1337  last_sync++;
1338  }
1339  if (NULL != plugin)
1340  {
1342  plugin = NULL;
1343  }
1344  if (NULL != filter)
1345  {
1347  filter = NULL;
1348  }
1349  if (NULL != stat_get)
1350  {
1352  stat_get = NULL;
1353  }
1354  if (NULL != stat_timeout_task)
1355  {
1357  stat_timeout_task = NULL;
1358  }
1360  plugin_name = NULL;
1361  if (last_sync > 0)
1362  sync_stats ();
1363  if (NULL != stats)
1364  {
1366  stats = NULL;
1367  }
1369  quota_stat_name = NULL;
1370 }
1371 
1372 
1381 static void *
1383  struct GNUNET_SERVICE_Client *client,
1384  struct GNUNET_MQ_Handle *mq)
1385 {
1386  return client;
1387 }
1388 
1389 
1398 static void
1400  struct GNUNET_SERVICE_Client *client,
1401  void *app_ctx)
1402 {
1403  struct ReservationList *pos;
1404  struct ReservationList *prev;
1405  struct ReservationList *next;
1406 
1407  GNUNET_assert (app_ctx == client);
1408  prev = NULL;
1409  pos = reservations;
1410  while (NULL != pos)
1411  {
1412  next = pos->next;
1413  if (pos->client == client)
1414  {
1415  if (NULL == prev)
1416  reservations = next;
1417  else
1418  prev->next = next;
1420  GNUNET_free (pos);
1421  }
1422  else
1423  {
1424  prev = pos;
1425  }
1426  pos = next;
1427  }
1429  gettext_noop ("# reserved"),
1430  reserved,
1431  GNUNET_NO);
1432 }
1433 
1434 
1442 static void
1443 run (void *cls,
1444  const struct GNUNET_CONFIGURATION_Handle *c,
1445  struct GNUNET_SERVICE_Handle *serv)
1446 {
1447  char *fn;
1448  char *pfn;
1449  unsigned int bf_size;
1450 
1451  service = serv;
1452  cfg = c;
1454  "DATASTORE",
1455  "DATABASE",
1456  &plugin_name))
1457  {
1459  "DATABASE",
1460  "DATASTORE");
1461  return;
1462  }
1464  _ ("# bytes used in file-sharing datastore `%s'"),
1465  plugin_name);
1466  if (GNUNET_OK !=
1467  GNUNET_CONFIGURATION_get_value_size (cfg, "DATASTORE", "QUOTA", &quota))
1468  {
1469  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "QUOTA", "DATASTORE");
1470  return;
1471  }
1472  stats = GNUNET_STATISTICS_create ("datastore", cfg);
1474  cache_size = quota / 8; /* Or should we make this an option? */
1476  gettext_noop ("# cache size"),
1477  cache_size,
1478  GNUNET_NO);
1479  if (quota / (32 * 1024LL) > MAX_BF_SIZE)
1480  bf_size = MAX_BF_SIZE;
1481  else
1482  bf_size =
1483  quota / (32 * 1024LL); /* 8 bit per entry, 1 bit per 32 kb in DB */
1484  fn = NULL;
1486  "DATASTORE",
1487  "BLOOMFILTER",
1488  &fn)) ||
1490  {
1492  _ ("Could not use specified filename `%s' for bloomfilter.\n"),
1493  NULL != fn ? fn : "");
1494  GNUNET_free (fn);
1495  fn = NULL;
1496  }
1497  if (NULL != fn)
1498  {
1499  GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name);
1500  if (GNUNET_YES == GNUNET_DISK_file_test (pfn))
1501  {
1502  filter =
1504  bf_size,
1505  5); /* approx. 3% false positives at max use */
1506  if (NULL == filter)
1507  {
1508  /* file exists but not valid, remove and try again, but refresh */
1509  if (0 != unlink (pfn))
1510  {
1511  /* failed to remove, run without file */
1513  _ ("Failed to remove bogus bloomfilter file `%s'\n"),
1514  pfn);
1515  GNUNET_free (pfn);
1516  pfn = NULL;
1518  NULL,
1519  bf_size,
1520  5); /* approx. 3% false positives at max use */
1522  }
1523  else
1524  {
1525  /* try again after remove */
1527  pfn,
1528  bf_size,
1529  5); /* approx. 3% false positives at max use */
1531  if (NULL == filter)
1532  {
1533  /* failed yet again, give up on using file */
1535  _ ("Failed to remove bogus bloomfilter file `%s'\n"),
1536  pfn);
1537  GNUNET_free (pfn);
1538  pfn = NULL;
1540  NULL,
1541  bf_size,
1542  5); /* approx. 3% false positives at max use */
1543  }
1544  }
1545  }
1546  else
1547  {
1548  /* normal case: have an existing valid bf file, no need to refresh */
1550  }
1551  }
1552  else
1553  {
1554  filter =
1556  bf_size,
1557  5); /* approx. 3% false positives at max use */
1559  }
1560  GNUNET_free (pfn);
1561  }
1562  else
1563  {
1564  filter =
1566  bf_size,
1567  5); /* approx. 3% false positives at max use */
1569  }
1570  GNUNET_free (fn);
1571  if (NULL == filter)
1572  {
1574  _ ("Failed to initialize bloomfilter.\n"));
1575  if (NULL != stats)
1576  {
1578  stats = NULL;
1579  }
1580  return;
1581  }
1584  "datastore",
1587  &process_stat_in,
1588  NULL);
1589  if (NULL == stat_get)
1591  else
1593  &stat_timeout,
1594  NULL);
1596 }
1597 
1598 
1603  "datastore",
1605  &run,
1608  NULL,
1609  GNUNET_MQ_hd_fixed_size (reserve,
1611  struct ReserveMessage,
1612  NULL),
1613  GNUNET_MQ_hd_fixed_size (release_reserve,
1615  struct ReleaseReserveMessage,
1616  NULL),
1617  GNUNET_MQ_hd_var_size (put,
1619  struct DataMessage,
1620  NULL),
1623  struct GetMessage,
1624  NULL),
1627  struct GetKeyMessage,
1628  NULL),
1629  GNUNET_MQ_hd_fixed_size (get_replication,
1631  struct GNUNET_MessageHeader,
1632  NULL),
1633  GNUNET_MQ_hd_fixed_size (get_zero_anonymity,
1635  struct GetZeroAnonymityMessage,
1636  NULL),
1637  GNUNET_MQ_hd_var_size (remove,
1639  struct DataMessage,
1640  NULL),
1643  struct GNUNET_MessageHeader,
1644  NULL),
1646 
1647 
1648 /* 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 int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:64
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
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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:302
#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:1184
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:1208
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:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2187
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2442
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2199
@ 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:404
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
#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:570
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:420
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
#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:1808