GNUnet  0.17.6
gnunet-service-statistics.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2010, 2012, 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 
26 #include "platform.h"
27 #include "gnunet_bio_lib.h"
28 #include "gnunet_container_lib.h"
29 #include "gnunet_disk_lib.h"
30 #include "gnunet_getopt_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_service_lib.h"
34 #include "gnunet_strings_lib.h"
35 #include "gnunet_time_lib.h"
36 #include "statistics.h"
37 
41 struct WatchEntry
42 {
46  struct WatchEntry *next;
47 
51  struct WatchEntry *prev;
52 
56  struct ClientEntry *ce;
57 
61  uint64_t last_value;
62 
66  uint32_t wid;
67 
73 };
74 
75 
80 struct SubsystemEntry;
81 
82 
86 struct StatsEntry
87 {
91  struct StatsEntry *next;
92 
96  struct StatsEntry *prev;
97 
102 
107  const char *name;
108 
113 
118 
122  uint64_t value;
123 
127  uint32_t uid;
128 
133 
138  int set;
139 };
140 
141 
147 {
152 
157 
162 
167 
172  const char *service;
173 };
174 
175 
179 struct ClientEntry
180 {
185 
189  struct GNUNET_MQ_Handle *mq;
190 
195 
199  uint32_t max_wid;
200 };
201 
202 
206 static const struct GNUNET_CONFIGURATION_Handle *cfg;
207 
211 static struct SubsystemEntry *sub_head;
212 
216 static struct SubsystemEntry *sub_tail;
217 
221 static unsigned int client_count;
222 
227 
231 static uint32_t uidgen;
232 
236 static int in_shutdown;
237 
238 
242 static void
244 {
245  struct SubsystemEntry *se;
246  struct StatsEntry *pos;
247  char *fn;
248  struct GNUNET_BIO_WriteHandle *wh;
249  uint16_t size;
250  unsigned long long total;
251  size_t nlen;
252  size_t slen;
254 
256  "STATISTICS",
257  "DATABASE",
258  &fn))
259  {
261  "STATISTICS",
262  "DATABASE");
263  return;
264  }
267  total = 0;
268  while (NULL != (se = sub_head))
269  {
271  slen = strlen (se->service) + 1;
272  while (NULL != (pos = se->stat_head))
273  {
275  if ((pos->persistent) && (NULL != wh))
276  {
277  nlen = strlen (pos->name) + 1;
278  size = sizeof(struct GNUNET_STATISTICS_SetMessage) + nlen + slen;
279  GNUNET_assert (size < UINT16_MAX);
280  msg = GNUNET_malloc (size);
281 
282  msg->header.size = htons ((uint16_t) size);
283  msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
284  GNUNET_assert (nlen + slen ==
285  GNUNET_STRINGS_buffer_fill ((char *) &msg[1],
286  nlen + slen,
287  2,
288  se->service,
289  pos->name));
290  msg->flags =
292  msg->value = GNUNET_htonll (pos->value);
293  if (GNUNET_OK != GNUNET_BIO_write (wh, "statistics-save-msg", msg,
294  size))
295  {
297  if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
299  wh = NULL;
300  }
301  else
302  {
303  total += size;
304  }
305  GNUNET_free (msg);
306  }
307  GNUNET_free (pos);
308  }
309  GNUNET_free (se);
310  }
311  if (NULL != wh)
312  {
313  if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
315  if (0 == total)
316  GNUNET_break (0 == unlink (fn));
317  else
319  _ ("Wrote %llu bytes of statistics to `%s'\n"),
320  total,
321  fn);
322  }
323  GNUNET_free (fn);
324 }
325 
326 
333 static void
334 transmit (struct ClientEntry *ce, const struct StatsEntry *e)
335 {
336  struct GNUNET_MQ_Envelope *env;
338  size_t size;
339 
340  size = strlen (e->subsystem->service) + 1 + strlen (e->name) + 1;
343  m->uid = htonl (e->uid);
344  if (e->persistent)
345  m->uid |= htonl (GNUNET_STATISTICS_PERSIST_BIT);
346  m->value = GNUNET_htonll (e->value);
348  size,
349  2,
350  e->subsystem->service,
351  e->name));
353  "Transmitting value for `%s:%s' (%d): %llu\n",
354  e->subsystem->service,
355  e->name,
356  e->persistent,
357  (unsigned long long) e->value);
358  GNUNET_MQ_send (ce->mq, env);
359 }
360 
361 
370 static void *
371 client_connect_cb (void *cls,
372  struct GNUNET_SERVICE_Client *c,
373  struct GNUNET_MQ_Handle *mq)
374 {
375  struct ClientEntry *ce;
376 
377  ce = GNUNET_new (struct ClientEntry);
378  ce->client = c;
379  ce->mq = mq;
380  client_count++;
382  return ce;
383 }
384 
385 
393 static int
394 check_get (void *cls, const struct GNUNET_MessageHeader *message)
395 {
396  const char *service;
397  const char *name;
398  size_t size;
399 
400  size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
401  if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
402  size,
403  2,
404  &service,
405  &name))
406  {
407  GNUNET_break (0);
408  return GNUNET_SYSERR;
409  }
410  return GNUNET_OK;
411 }
412 
413 
420 static void
421 handle_get (void *cls, const struct GNUNET_MessageHeader *message)
422 {
423  struct ClientEntry *ce = cls;
424  struct GNUNET_MQ_Envelope *env;
425  struct GNUNET_MessageHeader *end;
426  const char *service;
427  const char *name;
428  size_t slen;
429  size_t nlen;
430  struct SubsystemEntry *se;
431  struct StatsEntry *pos;
432  size_t size;
433 
434  size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
435  GNUNET_assert (size ==
436  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
437  size,
438  2,
439  &service,
440  &name));
441  slen = strlen (service);
442  nlen = strlen (name);
444  "Received request for statistics on `%s:%s'\n",
445  slen ? service : "*",
446  nlen ? name : "*");
447  for (se = sub_head; NULL != se; se = se->next)
448  {
449  if (! ((0 == slen) || (0 == strcmp (service, se->service))))
450  continue;
451  for (pos = se->stat_head; NULL != pos; pos = pos->next)
452  {
453  if (! ((0 == nlen) || (0 == strcmp (name, pos->name))))
454  continue;
455  transmit (ce, pos);
456  }
457  }
459  GNUNET_MQ_send (ce->mq, env);
461 }
462 
463 
469 static void
471 {
472  struct GNUNET_MQ_Envelope *env;
474  struct WatchEntry *pos;
475 
476  for (pos = se->we_head; NULL != pos; pos = pos->next)
477  {
478  if (GNUNET_YES == pos->last_value_set)
479  {
480  if (pos->last_value == se->value)
481  continue;
482  }
483  else
484  {
485  pos->last_value_set = GNUNET_YES;
486  }
488  wvm->flags =
490  wvm->wid = htonl (pos->wid);
491  wvm->reserved = htonl (0);
492  wvm->value = GNUNET_htonll (se->value);
493  GNUNET_MQ_send (pos->ce->mq, env);
494  pos->last_value = se->value;
495  }
496 }
497 
498 
507 static struct SubsystemEntry *
508 find_subsystem_entry (struct ClientEntry *ce, const char *service)
509 {
510  size_t slen;
511  struct SubsystemEntry *se;
512 
513  if (NULL != ce)
514  se = ce->subsystem;
515  else
516  se = NULL;
517  if ((NULL == se) || (0 != strcmp (service, se->service)))
518  {
519  for (se = sub_head; NULL != se; se = se->next)
520  if (0 == strcmp (service, se->service))
521  break;
522  if (NULL != ce)
523  ce->subsystem = se;
524  }
525  if (NULL != se)
526  return se;
528  "Allocating new subsystem entry `%s'\n",
529  service);
530  slen = strlen (service) + 1;
531  se = GNUNET_malloc (sizeof(struct SubsystemEntry) + slen);
532  GNUNET_memcpy (&se[1], service, slen);
533  se->service = (const char *) &se[1];
535  if (NULL != ce)
536  ce->subsystem = se;
537  return se;
538 }
539 
540 
548 static struct StatsEntry *
549 find_stat_entry (struct SubsystemEntry *se, const char *name)
550 {
551  struct StatsEntry *pos;
552 
553  for (pos = se->stat_head; NULL != pos; pos = pos->next)
554  if (0 == strcmp (name, pos->name))
555  return pos;
556  return NULL;
557 }
558 
559 
567 static int
568 check_set (void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
569 {
570  const char *service;
571  const char *name;
572  size_t msize;
573 
574  msize = ntohs (msg->header.size) - sizeof(*msg);
575  if (msize != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
576  msize,
577  2,
578  &service,
579  &name))
580  {
581  GNUNET_break (0);
582  return GNUNET_SYSERR;
583  }
584  return GNUNET_OK;
585 }
586 
587 
594 static void
595 handle_set (void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
596 {
597  struct ClientEntry *ce = cls;
598  const char *service;
599  const char *name;
600  size_t nlen;
601  uint16_t msize;
602  uint16_t size;
603  struct SubsystemEntry *se;
604  struct StatsEntry *pos;
605  uint32_t flags;
606  uint64_t value;
607  int64_t delta;
608  int changed;
609  int initial_set;
610 
611  msize = ntohs (msg->header.size);
612  size = msize - sizeof(struct GNUNET_STATISTICS_SetMessage);
613  GNUNET_assert (size == GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
614  size,
615  2,
616  &service,
617  &name));
618  se = find_subsystem_entry (ce, service);
619  flags = ntohl (msg->flags);
620  value = GNUNET_ntohll (msg->value);
622  "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
623  service,
624  name,
625  (unsigned int) flags,
626  (unsigned long long) value);
627  pos = find_stat_entry (se, name);
628  if (NULL != pos)
629  {
630  initial_set = 0;
632  {
633  changed = (pos->value != value);
634  pos->value = value;
635  }
636  else
637  {
638  delta = (int64_t) value;
639  if ((delta < 0) && (pos->value < -delta))
640  {
641  changed = (0 != pos->value);
642  pos->value = 0;
643  }
644  else
645  {
646  changed = (0 != delta);
647  GNUNET_break ((delta <= 0) || (pos->value + delta > pos->value));
648  pos->value += delta;
649  }
650  }
651  if (GNUNET_NO == pos->set)
652  {
653  pos->set = GNUNET_YES;
654  initial_set = 1;
655  }
657  if (pos != se->stat_head)
658  {
659  /* move to front for faster setting next time! */
662  }
664  "Statistic `%s:%s' updated to value %llu (%d).\n",
665  service,
666  name,
667  (unsigned long long) pos->value,
668  pos->persistent);
669  if ((changed) || (1 == initial_set))
670  notify_change (pos);
672  return;
673  }
674  /* not found, create a new entry */
675  nlen = strlen (name) + 1;
676  pos = GNUNET_malloc (sizeof(struct StatsEntry) + nlen);
677  GNUNET_memcpy (&pos[1], name, nlen);
678  pos->name = (const char *) &pos[1];
679  pos->subsystem = se;
680  if ((0 == (flags & GNUNET_STATISTICS_SETFLAG_RELATIVE)) ||
681  (0 < (int64_t) GNUNET_ntohll (msg->value)))
682  {
683  pos->value = GNUNET_ntohll (msg->value);
684  pos->set = GNUNET_YES;
685  }
686  else
687  {
688  pos->set = GNUNET_NO;
689  }
690  pos->uid = uidgen++;
694  "New statistic on `%s:%s' with value %llu created.\n",
695  service,
696  name,
697  (unsigned long long) pos->value);
698  if (NULL != ce)
700 }
701 
702 
710 static int
711 check_watch (void *cls, const struct GNUNET_MessageHeader *message)
712 {
713  size_t size;
714  const char *service;
715  const char *name;
716 
717  size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
718  if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
719  size,
720  2,
721  &service,
722  &name))
723  {
724  GNUNET_break (0);
725  return GNUNET_SYSERR;
726  }
727  return GNUNET_OK;
728 }
729 
730 
737 static void
738 handle_watch (void *cls, const struct GNUNET_MessageHeader *message)
739 {
740  struct ClientEntry *ce = cls;
741  const char *service;
742  const char *name;
743  uint16_t msize;
744  uint16_t size;
745  struct SubsystemEntry *se;
746  struct StatsEntry *pos;
747  struct WatchEntry *we;
748  size_t nlen;
749 
750  if (NULL == nc)
751  {
753  return;
754  }
756  msize = ntohs (message->size);
757  size = msize - sizeof(struct GNUNET_MessageHeader);
758  GNUNET_assert (size ==
759  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
760  size,
761  2,
762  &service,
763  &name));
765  "Received request to watch statistic on `%s:%s'\n",
766  service,
767  name);
768  se = find_subsystem_entry (ce, service);
769  pos = find_stat_entry (se, name);
770  if (NULL == pos)
771  {
772  nlen = strlen (name) + 1;
773  pos = GNUNET_malloc (sizeof(struct StatsEntry) + nlen);
774  GNUNET_memcpy (&pos[1], name, nlen);
775  pos->name = (const char *) &pos[1];
776  pos->subsystem = se;
778  pos->uid = uidgen++;
779  pos->set = GNUNET_NO;
781  "New statistic on `%s:%s' with value %llu created.\n",
782  service,
783  name,
784  (unsigned long long) pos->value);
785  }
786  we = GNUNET_new (struct WatchEntry);
787  we->ce = ce;
789  we->wid = ce->max_wid++;
791  if (0 != pos->value)
792  notify_change (pos);
794 }
795 
796 
805 static void
806 handle_disconnect (void *cls, const struct GNUNET_MessageHeader *message)
807 {
808  struct ClientEntry *ce = cls;
809  struct GNUNET_MQ_Envelope *env;
810  struct GNUNET_MessageHeader *msg;
811 
813  GNUNET_MQ_send (ce->mq, env);
815 }
816 
817 
821 static void
823 {
824  struct WatchEntry *we;
825  struct StatsEntry *pos;
826  struct SubsystemEntry *se;
827 
828  if (NULL == nc)
829  return;
830  save ();
832  nc = NULL;
834  while (NULL != (se = sub_head))
835  {
837  while (NULL != (pos = se->stat_head))
838  {
840  while (NULL != (we = pos->we_head))
841  {
842  GNUNET_break (0);
844  GNUNET_free (we);
845  }
846  GNUNET_free (pos);
847  }
848  GNUNET_free (se);
849  }
850 }
851 
852 
858 static void
859 shutdown_task (void *cls)
860 {
862  if (0 != client_count)
863  return;
864  do_shutdown ();
865 }
866 
867 
875 static void
877  struct GNUNET_SERVICE_Client *client,
878  void *app_cls)
879 {
880  struct ClientEntry *ce = app_cls;
881  struct WatchEntry *we;
882  struct WatchEntry *wen;
883  struct StatsEntry *pos;
884  struct SubsystemEntry *se;
885 
886  client_count--;
887  for (se = sub_head; NULL != se; se = se->next)
888  {
889  for (pos = se->stat_head; NULL != pos; pos = pos->next)
890  {
891  wen = pos->we_head;
892  while (NULL != (we = wen))
893  {
894  wen = we->next;
895  if (we->ce != ce)
896  continue;
898  GNUNET_free (we);
899  }
900  }
901  }
902  GNUNET_free (ce);
903  if ((0 == client_count) && (GNUNET_YES == in_shutdown))
904  do_shutdown ();
905 }
906 
907 
919 static int
920 inject_message (void *cls, const struct GNUNET_MessageHeader *message)
921 {
922  uint16_t msize = ntohs (message->size);
923  const struct GNUNET_STATISTICS_SetMessage *sm;
924 
925  sm = (const struct GNUNET_STATISTICS_SetMessage *) message;
926  if ((sizeof(struct GNUNET_STATISTICS_SetMessage) > msize) ||
927  (GNUNET_OK != check_set (NULL, sm)))
928  {
929  GNUNET_break (0);
930  return GNUNET_SYSERR;
931  }
932  handle_set (NULL, sm);
933  return GNUNET_OK;
934 }
935 
936 
941 static void
943 {
944  char *fn;
945  struct GNUNET_BIO_ReadHandle *rh;
946  uint64_t fsize;
947  char *buf;
948  struct GNUNET_MessageStreamTokenizer *mst;
949 
951  "STATISTICS",
952  "DATABASE",
953  &fn))
954  {
956  "STATISTICS",
957  "DATABASE");
958  return;
959  }
960  if ((GNUNET_OK !=
961  GNUNET_DISK_file_size (fn, &fsize, GNUNET_NO, GNUNET_YES)) ||
962  (0 == fsize))
963  {
964  GNUNET_free (fn);
965  return;
966  }
967  buf = GNUNET_malloc (fsize);
968  rh = GNUNET_BIO_read_open_file (fn);
969  if (! rh)
970  {
971  GNUNET_free (buf);
972  GNUNET_free (fn);
973  return;
974  }
975  if (GNUNET_OK != GNUNET_BIO_read (rh, fn, buf, fsize))
976  {
979  GNUNET_free (buf);
980  GNUNET_free (fn);
981  return;
982  }
984  _ ("Loading %llu bytes of statistics from `%s'\n"),
985  (unsigned long long) fsize,
986  fn);
987  mst = GNUNET_MST_create (&inject_message, NULL);
988  GNUNET_break (
989  GNUNET_OK ==
990  GNUNET_MST_from_buffer (mst, buf, (size_t) fsize, GNUNET_YES, GNUNET_NO));
991  GNUNET_MST_destroy (mst);
992  GNUNET_free (buf);
994  GNUNET_free (fn);
995 }
996 
997 
1005 static void
1006 run (void *cls,
1007  const struct GNUNET_CONFIGURATION_Handle *c,
1009 {
1010  cfg = c;
1012  load ();
1014 }
1015 
1016 
1021  "statistics",
1023  &run,
1026  NULL,
1027  GNUNET_MQ_hd_var_size (set,
1030  NULL),
1033  struct GNUNET_MessageHeader,
1034  NULL),
1037  struct GNUNET_MessageHeader,
1038  NULL),
1041  struct GNUNET_MessageHeader,
1042  NULL),
1044 
1045 
1046 #if defined(__linux__) && defined(__GLIBC__)
1047 #include <malloc.h>
1048 
1052 void __attribute__ ((constructor))
1053 GNUNET_STATISTICS_memory_init ()
1054 {
1055  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1056  mallopt (M_TOP_PAD, 1 * 1024);
1057  malloc_trim (0);
1058 }
1059 
1060 
1061 #endif
1062 
1063 
1064 /* end of gnunet-service-statistics.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
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static struct Experiment * e
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:66
enum RadiotapType __attribute__
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct StatsEntry * find_stat_entry(struct SubsystemEntry *se, const char *name)
Find the statistics entry of the given subsystem.
static void transmit(struct ClientEntry *ce, const struct StatsEntry *e)
Transmit the given stats value.
static void handle_set(void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
Handle SET-message.
static int check_watch(void *cls, const struct GNUNET_MessageHeader *message)
Check integrity of WATCH-message.
static void handle_watch(void *cls, const struct GNUNET_MessageHeader *message)
Handle WATCH-message.
static void handle_disconnect(void *cls, const struct GNUNET_MessageHeader *message)
Handle DISCONNECT-message.
static int inject_message(void *cls, const struct GNUNET_MessageHeader *message)
We've read a struct GNUNET_STATISTICS_SetMessage * from disk.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static unsigned int client_count
Number of connected clients.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
static struct GNUNET_NotificationContext * nc
Our notification context.
static struct SubsystemEntry * find_subsystem_entry(struct ClientEntry *ce, const char *service)
Find the subsystem entry of the given name for the specified client.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
A client disconnected.
static int in_shutdown
Set to GNUNET_YES if we are shutting down as soon as possible.
static void shutdown_task(void *cls)
Task run during shutdown.
static void handle_get(void *cls, const struct GNUNET_MessageHeader *message)
Handle GET-message.
static void save()
Write persistent statistics to disk.
static void notify_change(struct StatsEntry *se)
Notify all clients listening about a change to a value.
static void load()
Load persistent values from disk.
GNUNET_SERVICE_MAIN("statistics", GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(set, GNUNET_MESSAGE_TYPE_STATISTICS_SET, struct GNUNET_STATISTICS_SetMessage, NULL), GNUNET_MQ_hd_var_size(get, GNUNET_MESSAGE_TYPE_STATISTICS_GET, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_var_size(watch, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(disconnect, GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static struct SubsystemEntry * sub_tail
Tail of linked list of subsystems with active statistics.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Process statistics requests.
static void do_shutdown()
Actually perform the shutdown.
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
static int check_set(void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
Check format of SET-message.
static uint32_t uidgen
Counter used to generate unique values.
static int check_get(void *cls, const struct GNUNET_MessageHeader *message)
Check integrity of GET-message.
static struct GNUNET_TESTBED_BarrierWaitHandle * wh
Our barrier wait handle.
static char buf[2048]
static int watch
Watch value continuously.
Buffered IO library.
Container classes for GNUnet.
Disk IO APIs.
Command line parsing and –help formatting.
Constants for network protocols.
Functions related to starting services.
API to create, modify and access statistics.
Strings and string handling functions.
Functions related to time.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open_file(const char *fn)
Open a file for reading.
Definition: bio.c:119
int GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const char *what, const void *buffer, size_t n)
Write a buffer to a handle.
Definition: bio.c:796
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition: bio.c:609
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open handle.
Definition: bio.c:167
int GNUNET_BIO_read(struct GNUNET_BIO_ReadHandle *h, const char *what, void *result, size_t len)
Read some contents into a buffer.
Definition: bio.c:288
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition: bio.c:560
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_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:222
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_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#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
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:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
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:56
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:160
#define GNUNET_MESSAGE_TYPE_STATISTICS_END
Response to a STATISTICS_GET message (end of value stream).
#define GNUNET_MESSAGE_TYPE_STATISTICS_GET
Get a statistical value(s).
#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
Response to a STATISTICS_GET message (with value).
#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE
Changes to a watched value.
#define GNUNET_MESSAGE_TYPE_STATISTICS_SET
Set a statistical value.
#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
Service confirms disconnect and that it is done processing all requests from the client.
#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH
Watch changes to a statistical value.
#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT
Client is done sending service requests and will now disconnect.
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_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:418
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
int GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:114
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2412
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
unsigned int GNUNET_STRINGS_buffer_tokenize(const char *buffer, size_t size, unsigned int count,...)
Given a buffer of a given size, find "count" 0-terminated strings in the buffer and assign the count ...
Definition: strings.c:73
size_t GNUNET_STRINGS_buffer_fill(char *buffer, size_t size, unsigned int count,...)
Fill a buffer of the given size with count 0-terminated strings (given as varargs).
Definition: strings.c:45
static unsigned int size
Size of the "table".
Definition: peer.c:67
static void disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the peerstore service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define GNUNET_STATISTICS_PERSIST_BIT
Flag for the struct GNUNET_STATISTICS_ReplyMessage UID only.
Definition: statistics.h:65
#define GNUNET_STATISTICS_SETFLAG_PERSISTENT
The value being set is to be persistent (note that this bit can be combined with GNUNET_STATISTICS_SE...
Definition: statistics.h:83
#define GNUNET_STATISTICS_SETFLAG_RELATIVE
The value being set is a relative change.
Definition: statistics.h:75
Information about one of our clients.
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
struct SubsystemEntry * subsystem
Which subsystem is this client writing to (SET/UPDATE)?
uint32_t max_wid
Maximum watch ID used by this client so far.
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
Handle for buffered reading.
Definition: bio.c:74
Handle for buffered writing.
Definition: bio.c:518
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.
Handle to a message stream tokenizer.
Definition: mst.c:44
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:76
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
Statistics message.
Definition: statistics.h:41
Message to set a statistic.
Definition: statistics.h:92
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:102
Message transmitted if a watched value changes.
Definition: statistics.h:116
uint32_t reserved
Reserved (always 0).
Definition: statistics.h:139
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:126
uint32_t wid
Unique watch identification number (watch requests are enumerated in the order they are received,...
Definition: statistics.h:134
Entry in the statistics list.
uint64_t value
Our value.
struct StatsEntry * prev
This is a linked list.
struct StatsEntry * next
This is a linked list.
struct SubsystemEntry * subsystem
Subsystem this entry belongs to.
struct WatchEntry * we_tail
Watch context for changes to this value, or NULL for none.
uint32_t uid
Unique ID.
struct WatchEntry * we_head
Watch context for changes to this value, or NULL for none.
int persistent
Is this value persistent?
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
int set
Is this value set? GNUNET_NO: value is n/a, GNUNET_YES: value is valid.
We keep the statistics organized by subsystem for faster lookup during SET operations.
struct SubsystemEntry * prev
Subsystems are kept in a DLL.
struct SubsystemEntry * next
Subsystems are kept in a DLL.
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
struct StatsEntry * stat_tail
Tail of list of values kept for this subsystem.
const char * service
Name of the subsystem this entry is for, allocated at the end of this struct, do not free().
struct WatchEntry * next
Watch entries are kept in a linked list.
uint64_t last_value
Last value we communicated to the client for this watch entry.
struct WatchEntry * prev
Watch entries are kept in a linked list.
int last_value_set
Is last_value valid GNUNET_NO : last_value is n/a, GNUNET_YES: last_value is valid.
uint32_t wid
Unique watch number for this client and this watched value.
struct ClientEntry * ce
For which client is this watch entry?