GNUnet 0.22.2
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_util_lib.h"
28#include "gnunet_protocols.h"
29#include "gnunet_time_lib.h"
30#include "statistics.h"
31
36{
41
46
50 struct ClientEntry *ce;
51
55 uint64_t last_value;
56
60 uint32_t wid;
61
67};
68
69
74struct SubsystemEntry;
75
76
81{
86
91
96
101 const char *name;
102
107
112
116 uint64_t value;
117
121 uint32_t uid;
122
127
132 int set;
133};
134
135
141{
146
151
156
161
166 const char *service;
167};
168
169
173struct ClientEntry
174{
179
183 struct GNUNET_MQ_Handle *mq;
184
189
193 uint32_t max_wid;
194};
195
196
200static const struct GNUNET_CONFIGURATION_Handle *cfg;
201
206
211
215static unsigned int client_count;
216
221
225static uint32_t uidgen;
226
230static int in_shutdown;
231
232
236static void
238{
239 struct SubsystemEntry *se;
240 struct StatsEntry *pos;
241 char *fn;
242 struct GNUNET_BIO_WriteHandle *wh;
243 uint16_t size;
244 unsigned long long total;
245 size_t nlen;
246 size_t slen;
248
250 "STATISTICS",
251 "DATABASE",
252 &fn))
253 {
255 "STATISTICS",
256 "DATABASE");
257 return;
258 }
261 total = 0;
262 while (NULL != (se = sub_head))
263 {
265 slen = strlen (se->service) + 1;
266 while (NULL != (pos = se->stat_head))
267 {
269 if ((pos->persistent) && (NULL != wh))
270 {
271 nlen = strlen (pos->name) + 1;
272 size = sizeof(struct GNUNET_STATISTICS_SetMessage) + nlen + slen;
273 GNUNET_assert (size < UINT16_MAX);
275
276 msg->header.size = htons ((uint16_t) size);
278 GNUNET_assert (nlen + slen ==
279 GNUNET_STRINGS_buffer_fill ((char *) &msg[1],
280 nlen + slen,
281 2,
282 se->service,
283 pos->name));
284 msg->flags =
286 msg->value = GNUNET_htonll (pos->value);
287 if (GNUNET_OK != GNUNET_BIO_write (wh, "statistics-save-msg", msg,
288 size))
289 {
291 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
293 wh = NULL;
294 }
295 else
296 {
297 total += size;
298 }
300 }
301 GNUNET_free (pos);
302 }
303 GNUNET_free (se);
304 }
305 if (NULL != wh)
306 {
307 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
309 if (0 == total)
310 GNUNET_break (0 == unlink (fn));
311 else
313 _ ("Wrote %llu bytes of statistics to `%s'\n"),
314 total,
315 fn);
316 }
317 GNUNET_free (fn);
318}
319
320
327static void
328transmit (struct ClientEntry *ce, const struct StatsEntry *e)
329{
330 struct GNUNET_MQ_Envelope *env;
332 size_t size;
333
334 size = strlen (e->subsystem->service) + 1 + strlen (e->name) + 1;
337 m->uid = htonl (e->uid);
338 if (e->persistent)
339 m->uid |= htonl (GNUNET_STATISTICS_PERSIST_BIT);
340 m->value = GNUNET_htonll (e->value);
342 size,
343 2,
344 e->subsystem->service,
345 e->name));
347 "Transmitting value for `%s:%s' (%d): %llu\n",
348 e->subsystem->service,
349 e->name,
350 e->persistent,
351 (unsigned long long) e->value);
352 GNUNET_MQ_send (ce->mq, env);
353}
354
355
364static void *
366 struct GNUNET_SERVICE_Client *c,
367 struct GNUNET_MQ_Handle *mq)
368{
369 struct ClientEntry *ce;
370
371 ce = GNUNET_new (struct ClientEntry);
372 ce->client = c;
373 ce->mq = mq;
374 client_count++;
376 return ce;
377}
378
379
387static int
388check_get (void *cls, const struct GNUNET_MessageHeader *message)
389{
390 const char *service;
391 const char *name;
392 size_t size;
393
394 size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
395 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
396 size,
397 2,
398 &service,
399 &name))
400 {
401 GNUNET_break (0);
402 return GNUNET_SYSERR;
403 }
404 return GNUNET_OK;
405}
406
407
414static void
415handle_get (void *cls, const struct GNUNET_MessageHeader *message)
416{
417 struct ClientEntry *ce = cls;
418 struct GNUNET_MQ_Envelope *env;
420 const char *service;
421 const char *name;
422 size_t slen;
423 size_t nlen;
424 struct SubsystemEntry *se;
425 struct StatsEntry *pos;
426 size_t size;
427
428 size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
430 GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
431 size,
432 2,
433 &service,
434 &name));
435 slen = strlen (service);
436 nlen = strlen (name);
438 "Received request for statistics on `%s:%s'\n",
439 slen ? service : "*",
440 nlen ? name : "*");
441 for (se = sub_head; NULL != se; se = se->next)
442 {
443 if (! ((0 == slen) || (0 == strcmp (service, se->service))))
444 continue;
445 for (pos = se->stat_head; NULL != pos; pos = pos->next)
446 {
447 if (! ((0 == nlen) || (0 == strcmp (name, pos->name))))
448 continue;
449 transmit (ce, pos);
450 }
451 }
453 GNUNET_MQ_send (ce->mq, env);
455}
456
457
463static void
465{
466 struct GNUNET_MQ_Envelope *env;
468 struct WatchEntry *pos;
469
470 for (pos = se->we_head; NULL != pos; pos = pos->next)
471 {
472 if (GNUNET_YES == pos->last_value_set)
473 {
474 if (pos->last_value == se->value)
475 continue;
476 }
477 else
478 {
480 }
482 wvm->flags =
484 wvm->wid = htonl (pos->wid);
485 wvm->reserved = htonl (0);
486 wvm->value = GNUNET_htonll (se->value);
487 GNUNET_MQ_send (pos->ce->mq, env);
488 pos->last_value = se->value;
489 }
490}
491
492
501static struct SubsystemEntry *
502find_subsystem_entry (struct ClientEntry *ce, const char *service)
503{
504 size_t slen;
505 struct SubsystemEntry *se;
506
507 if (NULL != ce)
508 se = ce->subsystem;
509 else
510 se = NULL;
511 if ((NULL == se) || (0 != strcmp (service, se->service)))
512 {
513 for (se = sub_head; NULL != se; se = se->next)
514 if (0 == strcmp (service, se->service))
515 break;
516 if (NULL != ce)
517 ce->subsystem = se;
518 }
519 if (NULL != se)
520 return se;
522 "Allocating new subsystem entry `%s'\n",
523 service);
524 slen = strlen (service) + 1;
525 se = GNUNET_malloc (sizeof(struct SubsystemEntry) + slen);
526 GNUNET_memcpy (&se[1], service, slen);
527 se->service = (const char *) &se[1];
529 if (NULL != ce)
530 ce->subsystem = se;
531 return se;
532}
533
534
542static struct StatsEntry *
543find_stat_entry (struct SubsystemEntry *se, const char *name)
544{
545 struct StatsEntry *pos;
546
547 for (pos = se->stat_head; NULL != pos; pos = pos->next)
548 if (0 == strcmp (name, pos->name))
549 return pos;
550 return NULL;
551}
552
553
561static int
563{
564 const char *service;
565 const char *name;
566 size_t msize;
567
568 msize = ntohs (msg->header.size) - sizeof(*msg);
569 if (msize != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
570 msize,
571 2,
572 &service,
573 &name))
574 {
575 GNUNET_break (0);
576 return GNUNET_SYSERR;
577 }
578 return GNUNET_OK;
579}
580
581
588static void
590{
591 struct ClientEntry *ce = cls;
592 const char *service;
593 const char *name;
594 size_t nlen;
595 uint16_t msize;
596 uint16_t size;
597 struct SubsystemEntry *se;
598 struct StatsEntry *pos;
599 uint32_t flags;
600 uint64_t value;
601 int64_t delta;
602 int changed;
603 int initial_set;
604
605 msize = ntohs (msg->header.size);
606 size = msize - sizeof(struct GNUNET_STATISTICS_SetMessage);
608 size,
609 2,
610 &service,
611 &name));
612 se = find_subsystem_entry (ce, service);
613 flags = ntohl (msg->flags);
614 value = GNUNET_ntohll (msg->value);
616 "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
617 service,
618 name,
619 (unsigned int) flags,
620 (unsigned long long) value);
621 pos = find_stat_entry (se, name);
622 if (NULL != pos)
623 {
624 initial_set = 0;
626 {
627 changed = (pos->value != value);
628 pos->value = value;
629 }
630 else
631 {
632 delta = (int64_t) value;
633 if ((delta < 0) && (pos->value < -delta))
634 {
635 changed = (0 != pos->value);
636 pos->value = 0;
637 }
638 else
639 {
640 changed = (0 != delta);
641 GNUNET_break ((delta <= 0) || (pos->value + delta > pos->value));
642 pos->value += delta;
643 }
644 }
645 if (GNUNET_NO == pos->set)
646 {
647 pos->set = GNUNET_YES;
648 initial_set = 1;
649 }
651 if (pos != se->stat_head)
652 {
653 /* move to front for faster setting next time! */
656 }
658 "Statistic `%s:%s' updated to value %llu (%d).\n",
659 service,
660 name,
661 (unsigned long long) pos->value,
662 pos->persistent);
663 if ((changed) || (1 == initial_set))
664 notify_change (pos);
666 return;
667 }
668 /* not found, create a new entry */
669 nlen = strlen (name) + 1;
670 pos = GNUNET_malloc (sizeof(struct StatsEntry) + nlen);
671 GNUNET_memcpy (&pos[1], name, nlen);
672 pos->name = (const char *) &pos[1];
673 pos->subsystem = se;
675 (0 < (int64_t) GNUNET_ntohll (msg->value)))
676 {
677 pos->value = GNUNET_ntohll (msg->value);
678 pos->set = GNUNET_YES;
679 }
680 else
681 {
682 pos->set = GNUNET_NO;
683 }
684 pos->uid = uidgen++;
688 "New statistic on `%s:%s' with value %llu created.\n",
689 service,
690 name,
691 (unsigned long long) pos->value);
692 if (NULL != ce)
694}
695
696
704static int
705check_watch (void *cls, const struct GNUNET_MessageHeader *message)
706{
707 size_t size;
708 const char *service;
709 const char *name;
710
711 size = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
712 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
713 size,
714 2,
715 &service,
716 &name))
717 {
718 GNUNET_break (0);
719 return GNUNET_SYSERR;
720 }
721 return GNUNET_OK;
722}
723
724
731static void
732handle_watch (void *cls, const struct GNUNET_MessageHeader *message)
733{
734 struct ClientEntry *ce = cls;
735 const char *service;
736 const char *name;
737 uint16_t msize;
738 uint16_t size;
739 struct SubsystemEntry *se;
740 struct StatsEntry *pos;
741 struct WatchEntry *we;
742 size_t nlen;
743
744 if (NULL == nc)
745 {
747 return;
748 }
750 msize = ntohs (message->size);
751 size = msize - sizeof(struct GNUNET_MessageHeader);
753 GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
754 size,
755 2,
756 &service,
757 &name));
759 "Received request to watch statistic on `%s:%s'\n",
760 service,
761 name);
762 se = find_subsystem_entry (ce, service);
763 pos = find_stat_entry (se, name);
764 if (NULL == pos)
765 {
766 nlen = strlen (name) + 1;
767 pos = GNUNET_malloc (sizeof(struct StatsEntry) + nlen);
768 GNUNET_memcpy (&pos[1], name, nlen);
769 pos->name = (const char *) &pos[1];
770 pos->subsystem = se;
772 pos->uid = uidgen++;
773 pos->set = GNUNET_NO;
775 "New statistic on `%s:%s' with value %llu created.\n",
776 service,
777 name,
778 (unsigned long long) pos->value);
779 }
780 we = GNUNET_new (struct WatchEntry);
781 we->ce = ce;
783 we->wid = ce->max_wid++;
785 if (0 != pos->value)
786 notify_change (pos);
788}
789
790
799static void
800handle_disconnect (void *cls, const struct GNUNET_MessageHeader *message)
801{
802 struct ClientEntry *ce = cls;
803 struct GNUNET_MQ_Envelope *env;
805
807 GNUNET_MQ_send (ce->mq, env);
809}
810
811
815static void
817{
818 struct WatchEntry *we;
819 struct StatsEntry *pos;
820 struct SubsystemEntry *se;
821
822 if (NULL == nc)
823 return;
824 save ();
826 nc = NULL;
828 while (NULL != (se = sub_head))
829 {
831 while (NULL != (pos = se->stat_head))
832 {
834 while (NULL != (we = pos->we_head))
835 {
836 GNUNET_break (0);
838 GNUNET_free (we);
839 }
840 GNUNET_free (pos);
841 }
842 GNUNET_free (se);
843 }
844}
845
846
852static void
853shutdown_task (void *cls)
854{
856 if (0 != client_count)
857 return;
858 do_shutdown ();
859}
860
861
869static void
871 struct GNUNET_SERVICE_Client *client,
872 void *app_cls)
873{
874 struct ClientEntry *ce = app_cls;
875 struct WatchEntry *we;
876 struct WatchEntry *wen;
877 struct StatsEntry *pos;
878 struct SubsystemEntry *se;
879
880 client_count--;
881 for (se = sub_head; NULL != se; se = se->next)
882 {
883 for (pos = se->stat_head; NULL != pos; pos = pos->next)
884 {
885 wen = pos->we_head;
886 while (NULL != (we = wen))
887 {
888 wen = we->next;
889 if (we->ce != ce)
890 continue;
892 GNUNET_free (we);
893 }
894 }
895 }
896 GNUNET_free (ce);
897 if ((0 == client_count) && (GNUNET_YES == in_shutdown))
898 do_shutdown ();
899}
900
901
913static int
914inject_message (void *cls, const struct GNUNET_MessageHeader *message)
915{
916 uint16_t msize = ntohs (message->size);
917 const struct GNUNET_STATISTICS_SetMessage *sm;
918
919 sm = (const struct GNUNET_STATISTICS_SetMessage *) message;
920 if ((sizeof(struct GNUNET_STATISTICS_SetMessage) > msize) ||
921 (GNUNET_OK != check_set (NULL, sm)))
922 {
923 GNUNET_break (0);
924 return GNUNET_SYSERR;
925 }
926 handle_set (NULL, sm);
927 return GNUNET_OK;
928}
929
930
935static void
937{
938 char *fn;
939 struct GNUNET_BIO_ReadHandle *rh;
940 uint64_t fsize;
941 char *buf;
943
945 "STATISTICS",
946 "DATABASE",
947 &fn))
948 {
950 "STATISTICS",
951 "DATABASE");
952 return;
953 }
954 if ((GNUNET_OK !=
956 (0 == fsize))
957 {
958 GNUNET_free (fn);
959 return;
960 }
961 buf = GNUNET_malloc (fsize);
963 if (! rh)
964 {
965 GNUNET_free (buf);
966 GNUNET_free (fn);
967 return;
968 }
969 if (GNUNET_OK != GNUNET_BIO_read (rh, fn, buf, fsize))
970 {
973 GNUNET_free (buf);
974 GNUNET_free (fn);
975 return;
976 }
978 _ ("Loading %llu bytes of statistics from `%s'\n"),
979 (unsigned long long) fsize,
980 fn);
981 mst = GNUNET_MST_create (&inject_message, NULL);
983 GNUNET_OK ==
984 GNUNET_MST_from_buffer (mst, buf, (size_t) fsize, GNUNET_YES, GNUNET_NO));
985 GNUNET_MST_destroy (mst);
986 GNUNET_free (buf);
988 GNUNET_free (fn);
989}
990
991
999static void
1000run (void *cls,
1001 const struct GNUNET_CONFIGURATION_Handle *c,
1003{
1004 cfg = c;
1006 load ();
1008}
1009
1010
1016 "statistics",
1018 &run,
1021 NULL,
1025 NULL),
1028 struct GNUNET_MessageHeader,
1029 NULL),
1032 struct GNUNET_MessageHeader,
1033 NULL),
1036 struct GNUNET_MessageHeader,
1037 NULL),
1039
1040
1041#if defined(__linux__) && defined(__GLIBC__)
1042#include <malloc.h>
1043
1044void __attribute__((constructor))
1045GNUNET_STATISTICS_memory_init(void);
1046
1050void __attribute__ ((constructor))
1051GNUNET_STATISTICS_memory_init (void)
1052{
1053 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1054 mallopt (M_TOP_PAD, 1 * 1024);
1055 malloc_trim (0);
1056}
1057
1058
1059#endif
1060
1061
1062/* 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:103
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:62
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
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 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 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.
GNUNET_SERVICE_MAIN(GNUNET_OS_project_data_gnunet(), "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 const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static unsigned int client_count
Number of connected clients.
static struct GNUNET_NotificationContext * nc
Our notification context.
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.
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 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 SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
static struct StatsEntry * find_stat_entry(struct SubsystemEntry *se, const char *name)
Find the statistics entry of the given subsystem.
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 int watch
Watch value continuously.
struct GNUNET_PQ_ResultSpec __attribute__
Constants for network protocols.
Functions related to time.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue 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:291
enum GNUNET_GenericReturnValue GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition: bio.c:556
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition: bio.c:508
enum GNUNET_GenericReturnValue 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:750
enum GNUNET_GenericReturnValue GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open handle.
Definition: bio.c:162
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open_file(const char *fn)
Open a file for reading.
Definition: bio.c:114
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:606
#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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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:138
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:305
#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:61
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:76
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#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:161
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#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:1339
enum GNUNET_GenericReturnValue 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:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2483
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2418
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2389
@ 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:71
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:43
static unsigned int size
Size of the "table".
Definition: peer.c:68
static void disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the peerstore service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
#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:69
Handle for buffered writing.
Definition: bio.c:466
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
Handle to a message stream tokenizer.
Definition: mst.c:45
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
Handle to a client that is connected to a service.
Definition: service.c:249
Handle to a service.
Definition: service.c:116
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?