GNUnet debian-0.24.3-28-g4f2a77692
 
Loading...
Searching...
No Matches
statistics_api.c File Reference

API of the statistics service. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_constants.h"
#include "gnunet_protocols.h"
#include "gnunet_statistics_service.h"
#include "statistics.h"
Include dependency graph for statistics_api.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_STATISTICS_WatchEntry
 Entry kept for each value we are watching. More...
 
struct  GNUNET_STATISTICS_GetHandle
 Linked list of things we still need to do. More...
 
struct  GNUNET_STATISTICS_Handle
 Handle for the service. More...
 

Macros

#define SET_TRANSMIT_TIMEOUT
 How long do we wait until a statistics request for setting a value times out? (The update will be lost if the service does not react within this timeframe).
 
#define LOG(kind, ...)   GNUNET_log_from (kind, "statistics-api", __VA_ARGS__)
 

Enumerations

enum  ActionType { ACTION_GET , ACTION_SET , ACTION_UPDATE , ACTION_WATCH }
 Types of actions. More...
 

Functions

static void update_memory_statistics (struct GNUNET_STATISTICS_Handle *h)
 Obtain statistics about this process's memory consumption and report those as well (if they changed).
 
static void reconnect_later (struct GNUNET_STATISTICS_Handle *h)
 Reconnect at a later time, respecting back-off.
 
static void schedule_action (void *cls)
 Schedule the next action to be performed.
 
static void schedule_watch_request (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_WatchEntry *watch)
 Transmit request to service that we want to watch the development of a particular value.
 
static void free_action_item (struct GNUNET_STATISTICS_GetHandle *gh)
 Free memory associated with the given action item.
 
static void do_disconnect (struct GNUNET_STATISTICS_Handle *h)
 Disconnect from the statistics service.
 
static int check_statistics_value (void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
 Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
 
static void handle_statistics_value (void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
 Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
 
static void handle_statistics_watch_value (void *cls, const struct GNUNET_STATISTICS_WatchValueMessage *wvm)
 We have received a watch value from the service.
 
static void mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.
 
static void do_destroy (void *cls)
 Task used to destroy the statistics handle.
 
static void handle_disconnect_confirm (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM message.
 
static void handle_statistics_end (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a GNUNET_MESSAGE_TYPE_STATISTICS_END message.
 
static int try_connect (struct GNUNET_STATISTICS_Handle *h)
 Try to (re)connect to the statistics service.
 
static void reconnect_task (void *cls)
 We've waited long enough, reconnect now.
 
static void transmit_get (struct GNUNET_STATISTICS_Handle *handle)
 Transmit a GET request (and if successful, start to receive the response).
 
static void transmit_watch (struct GNUNET_STATISTICS_Handle *handle)
 Transmit a WATCH request (and if successful, start to receive the response).
 
static void transmit_set (struct GNUNET_STATISTICS_Handle *handle)
 Transmit a SET/UPDATE request.
 
struct GNUNET_STATISTICS_HandleGNUNET_STATISTICS_create (const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Get handle for the statistics service.
 
void GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first)
 Destroy a handle (free all state associated with it).
 
struct GNUNET_STATISTICS_GetHandleGNUNET_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.
 
void GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
 Cancel a GNUNET_STATISTICS_get request.
 
int GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
 Watch statistics from the peer (be notified whenever they change).
 
int GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
 Stop watching statistics from the peer.
 
static void add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name, int make_persistent, uint64_t value, enum ActionType type)
 Queue a request to change a statistic.
 
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.
 

Detailed Description

API of the statistics service.

Author
Christian Grothoff

Definition in file statistics_api.c.

Macro Definition Documentation

◆ SET_TRANSMIT_TIMEOUT

#define SET_TRANSMIT_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How long do we wait until a statistics request for setting a value times out? (The update will be lost if the service does not react within this timeframe).

Definition at line 38 of file statistics_api.c.

46{
51
56
61
66};
67
68
73{
77 char *subsystem;
78
82 char *name;
83
88
92 void *proc_cls;
93};
94
95
100{
105
110
115
119 char *subsystem;
120
124 char *name;
125
130
135
139 void *cls;
140
145
149 uint64_t value;
150
154 int make_persistent;
155
159 int aborted;
160
164 enum ActionType type;
165
169 uint16_t msize;
170};
171
172
177{
181 char *subsystem;
182
186 const struct GNUNET_CONFIGURATION_Handle *cfg;
187
191 struct GNUNET_MQ_Handle *mq;
192
198
203
210
215
220
225
230
234 uint64_t peak_heap_size;
235
239 uint64_t peak_rss;
240
244 unsigned int watches_size;
245
250 int do_destroy;
251
255 int receiving;
256};
257
258
263static void
265{
266#if ENABLE_HEAP_STATISTICS
267 uint64_t current_heap_size = 0;
268 uint64_t current_rss = 0;
269
270 if (GNUNET_NO != h->do_destroy)
271 return;
272#if HAVE_MALLINFO2
273 {
274 struct mallinfo2 mi;
275
276 mi = mallinfo2 ();
277 current_heap_size = mi.uordblks + mi.fordblks;
278 }
279#endif
280#if HAVE_GETRUSAGE
281 {
282 struct rusage ru;
283
284 if (0 == getrusage (RUSAGE_SELF, &ru))
285 {
286 current_rss = 1024LL * ru.ru_maxrss;
287 }
288 }
289#endif
290 if (current_heap_size > h->peak_heap_size)
291 {
292 h->peak_heap_size = current_heap_size;
294 "# peak heap size",
295 current_heap_size,
296 GNUNET_NO);
297 }
298 if (current_rss > h->peak_rss)
299 {
300 h->peak_rss = current_rss;
302 "# peak resident set size",
303 current_rss,
304 GNUNET_NO);
305 }
306#endif
307}
308
309
315static void
317
318
324static void
325schedule_action (void *cls);
326
327
335static void
338{
340 size_t slen;
341 size_t nlen;
342 size_t nsize;
343
344 slen = strlen (watch->subsystem) + 1;
345 nlen = strlen (watch->name) + 1;
346 nsize = sizeof(struct GNUNET_MessageHeader) + slen + nlen;
347 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
348 {
349 GNUNET_break (0);
350 return;
351 }
353 ai->sh = h;
354 ai->subsystem = GNUNET_strdup (watch->subsystem);
355 ai->name = GNUNET_strdup (watch->name);
357 ai->msize = nsize;
358 ai->type = ACTION_WATCH;
359 ai->proc = watch->proc;
360 ai->cls = watch->proc_cls;
362 h->action_tail,
363 ai);
365}
366
367
373static void
375{
377 GNUNET_free (gh->name);
378 GNUNET_free (gh);
379}
380
381
387static void
389{
391
392 h->receiving = GNUNET_NO;
393 if (NULL != (c = h->current))
394 {
395 h->current = NULL;
396 if ((NULL != c->cont) &&
397 (GNUNET_YES != c->aborted))
398 {
399 c->cont (c->cls,
401 c->cont = NULL;
402 }
404 }
405 if (NULL != h->mq)
406 {
408 h->mq = NULL;
409 }
410}
411
412
420static int
422 const struct GNUNET_STATISTICS_ReplyMessage *smsg)
423{
424 const char *service;
425 const char *name;
426 uint16_t size;
427
428 size = ntohs (smsg->header.size);
429 size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
430 if (size !=
431 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
432 size,
433 2,
434 &service,
435 &name))
436 {
437 GNUNET_break (0);
438 return GNUNET_SYSERR;
439 }
440 return GNUNET_OK;
441}
442
443
451static void
452handle_statistics_value (void *cls,
453 const struct GNUNET_STATISTICS_ReplyMessage *smsg)
454{
455 struct GNUNET_STATISTICS_Handle *h = cls;
456 const char *service;
457 const char *name;
458 uint16_t size;
459
460 if (h->current->aborted)
461 return; /* iteration aborted, don't bother */
462
463 size = ntohs (smsg->header.size);
464 size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
466 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
467 size,
468 2,
469 &service,
470 &name));
472 "Received valid statistic on `%s:%s': %llu\n",
473 service, name,
474 (unsigned long long) GNUNET_ntohll (smsg->value));
475 if (GNUNET_OK !=
476 h->current->proc (h->current->cls,
477 service,
478 name,
479 GNUNET_ntohll (smsg->value),
480 (0 !=
481 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)) ))
482 {
484 "Processing of remaining statistics aborted by client.\n");
485 h->current->aborted = GNUNET_YES;
486 }
487}
488
489
496static void
498 const struct
500{
501 struct GNUNET_STATISTICS_Handle *h = cls;
503 uint32_t wid;
504
505 GNUNET_break (0 == ntohl (wvm->reserved));
506 wid = ntohl (wvm->wid);
507 if (wid >= h->watches_size)
508 {
511 return;
512 }
513 w = h->watches[wid];
514 if (NULL == w)
515 return;
516 (void) w->proc (w->proc_cls,
517 w->subsystem,
518 w->name,
519 GNUNET_ntohll (wvm->value),
520 0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
521}
522
523
532static void
533mq_error_handler (void *cls,
534 enum GNUNET_MQ_Error error)
535{
536 struct GNUNET_STATISTICS_Handle *h = cls;
537
538 if (GNUNET_NO != h->do_destroy)
539 {
540 h->do_destroy = GNUNET_NO;
541 if (NULL != h->destroy_task)
542 {
543 GNUNET_SCHEDULER_cancel (h->destroy_task);
544 h->destroy_task = NULL;
545 }
547 GNUNET_NO);
548 return;
549 }
552}
553
554
560static void
561do_destroy (void *cls)
562{
563 struct GNUNET_STATISTICS_Handle *h = cls;
564
565 h->destroy_task = NULL;
566 h->do_destroy = GNUNET_NO;
568 "Running final destruction\n");
570 GNUNET_NO);
571}
572
573
582static void
584 const struct GNUNET_MessageHeader *msg)
585{
586 struct GNUNET_STATISTICS_Handle *h = cls;
587
588 if (GNUNET_SYSERR != h->do_destroy)
589 {
590 /* not in shutdown, why do we get 'TEST'? */
591 GNUNET_break (0);
594 return;
595 }
597 "Received DISCONNNECT_CONFIRM message from statistics, can complete disconnect\n");
598 if (NULL != h->destroy_task)
599 GNUNET_SCHEDULER_cancel (h->destroy_task);
600 h->destroy_task = GNUNET_SCHEDULER_add_now (&do_destroy,
601 h);
602}
603
604
613static void
614handle_statistics_end (void *cls,
615 const struct GNUNET_MessageHeader *msg)
616{
617 struct GNUNET_STATISTICS_Handle *h = cls;
619
621 "Received end of statistics marker\n");
622 if (NULL == (c = h->current))
623 {
624 GNUNET_break (0);
627 return;
628 }
630 h->current = NULL;
632 if (NULL != c->cont)
633 {
634 c->cont (c->cls,
635 GNUNET_OK);
636 c->cont = NULL;
637 }
639}
640
641
648static int
650{
652 GNUNET_MQ_hd_fixed_size (disconnect_confirm,
655 h),
656 GNUNET_MQ_hd_fixed_size (statistics_end,
659 h),
660 GNUNET_MQ_hd_var_size (statistics_value,
663 h),
664 GNUNET_MQ_hd_fixed_size (statistics_watch_value,
667 h),
669 };
672
673 if (NULL != h->backoff_task)
674 return GNUNET_NO;
675 if (NULL != h->mq)
676 return GNUNET_YES;
678 "statistics",
679 handlers,
681 h);
682 if (NULL == h->mq)
683 {
685 "Failed to connect to statistics service!\n");
686 return GNUNET_NO;
687 }
688 gn = h->action_head;
689 while (NULL != (gh = gn))
690 {
691 gn = gh->next;
692 if (gh->type == ACTION_WATCH)
693 {
694 GNUNET_CONTAINER_DLL_remove (h->action_head,
695 h->action_tail,
696 gh);
697 free_action_item (gh);
698 }
699 }
700 for (unsigned int i = 0; i < h->watches_size; i++)
701 if (NULL != h->watches[i])
703 h->watches[i]);
704 return GNUNET_YES;
705}
706
707
713static void
714reconnect_task (void *cls)
715{
716 struct GNUNET_STATISTICS_Handle *h = cls;
717
718 h->backoff_task = NULL;
720}
721
722
728static void
730{
731 int loss;
733
734 GNUNET_assert (NULL == h->backoff_task);
735 if (GNUNET_YES == h->do_destroy)
736 {
737 /* So we are shutting down and the service is not reachable.
738 * Chances are that it's down for good and we are not going to connect to
739 * it anymore.
740 * Give up and don't sync the rest of the data.
741 */loss = GNUNET_NO;
742 for (gh = h->action_head; NULL != gh; gh = gh->next)
743 if ((gh->make_persistent) &&
744 (ACTION_SET == gh->type))
745 loss = GNUNET_YES;
746 if (GNUNET_YES == loss)
748 _ ("Could not save some persistent statistics\n"));
749 if (NULL != h->destroy_task)
750 GNUNET_SCHEDULER_cancel (h->destroy_task);
751 h->destroy_task = GNUNET_SCHEDULER_add_now (&do_destroy,
752 h);
753 return;
754 }
755 h->backoff_task
758 h);
759 h->backoff = GNUNET_TIME_STD_BACKOFF (h->backoff);
760}
761
762
769static void
771{
773 struct GNUNET_MessageHeader *hdr;
774 struct GNUNET_MQ_Envelope *env;
775 size_t slen1;
776 size_t slen2;
777
778 GNUNET_assert (NULL != (c = handle->current));
779 slen1 = strlen (c->subsystem) + 1;
780 slen2 = strlen (c->name) + 1;
782 slen1 + slen2,
784 GNUNET_assert (slen1 + slen2 ==
785 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
786 slen1 + slen2,
787 2,
788 c->subsystem,
789 c->name));
792 handle);
794 env);
795}
796
797
804static void
806{
807 struct GNUNET_MessageHeader *hdr;
808 struct GNUNET_MQ_Envelope *env;
809 size_t slen1;
810 size_t slen2;
811
813 "Transmitting watch request for `%s'\n",
814 handle->current->name);
815 slen1 = strlen (handle->current->subsystem) + 1;
816 slen2 = strlen (handle->current->name) + 1;
818 slen1 + slen2,
820 GNUNET_assert (slen1 + slen2 ==
821 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
822 slen1 + slen2,
823 2,
824 handle->current->subsystem,
825 handle->current->name));
828 handle);
830 env);
831 GNUNET_assert (NULL == handle->current->cont);
832 free_action_item (handle->current);
833 handle->current = NULL;
835}
836
837
843static void
845{
847 struct GNUNET_MQ_Envelope *env;
848 size_t slen;
849 size_t nlen;
850
851 slen = strlen (handle->current->subsystem) + 1;
852 nlen = strlen (handle->current->name) + 1;
854 slen + nlen,
856 r->flags = 0;
857 r->value = GNUNET_htonll (handle->current->value);
858 if (handle->current->make_persistent)
860 if (handle->current->type == ACTION_UPDATE)
862 GNUNET_assert (slen + nlen ==
863 GNUNET_STRINGS_buffer_fill ((char *) &r[1],
864 slen + nlen,
865 2,
866 handle->current->subsystem,
867 handle->current->name));
868 GNUNET_assert (NULL == handle->current->cont);
869 free_action_item (handle->current);
870 handle->current = NULL;
874 handle);
876 env);
877}
878
879
889 const struct GNUNET_CONFIGURATION_Handle *cfg)
890{
892
893 if (GNUNET_YES ==
895 "statistics",
896 "DISABLE"))
897 return NULL;
899 h->cfg = cfg;
900 h->subsystem = GNUNET_strdup (subsystem);
902 return h;
903}
904
905
914void
916 int sync_first)
917{
918 struct GNUNET_STATISTICS_GetHandle *pos;
920
921 if (NULL == h)
922 return;
923 GNUNET_assert (GNUNET_NO == h->do_destroy); /* Don't call twice. */
924 if ((sync_first) &&
925 (NULL != h->mq) &&
926 (0 != GNUNET_MQ_get_length (h->mq)))
927 {
928 if ((NULL != h->current) &&
929 (ACTION_GET == h->current->type))
930 h->current->aborted = GNUNET_YES;
931 next = h->action_head;
932 while (NULL != (pos = next))
933 {
934 next = pos->next;
935 if ((ACTION_GET == pos->type) ||
936 (ACTION_WATCH == pos->type))
937 {
938 GNUNET_CONTAINER_DLL_remove (h->action_head,
939 h->action_tail,
940 pos);
941 free_action_item (pos);
942 }
943 }
944 h->do_destroy = GNUNET_YES;
946 GNUNET_assert (NULL == h->destroy_task);
947 h->destroy_task
949 5),
950 &do_destroy,
951 h);
953 "Deferring destruction\n");
954 return; /* do not finish destruction just yet */
955 }
956 /* do clean up all */
958 "Cleaning all up\n");
959 while (NULL != (pos = h->action_head))
960 {
961 GNUNET_CONTAINER_DLL_remove (h->action_head,
962 h->action_tail,
963 pos);
964 free_action_item (pos);
965 }
967 if (NULL != h->backoff_task)
968 {
969 GNUNET_SCHEDULER_cancel (h->backoff_task);
970 h->backoff_task = NULL;
971 }
972 if (NULL != h->destroy_task)
973 {
974 GNUNET_break (0);
975 GNUNET_SCHEDULER_cancel (h->destroy_task);
976 h->destroy_task = NULL;
977 }
978 for (unsigned int i = 0; i < h->watches_size; i++)
979 {
980 if (NULL == h->watches[i])
981 continue;
982 GNUNET_free (h->watches[i]->subsystem);
983 GNUNET_free (h->watches[i]->name);
984 GNUNET_free (h->watches[i]);
985 }
986 GNUNET_array_grow (h->watches,
987 h->watches_size,
988 0);
989 GNUNET_free (h->subsystem);
990 GNUNET_free (h);
991}
992
993
999static void
1000schedule_action (void *cls)
1001{
1002 struct GNUNET_STATISTICS_Handle *h = cls;
1003
1004 if (NULL != h->backoff_task)
1005 return; /* action already pending */
1006 if (GNUNET_YES != try_connect (h))
1007 {
1009 return;
1010 }
1011 if (0 < GNUNET_MQ_get_length (h->mq))
1012 return; /* Wait for queue to be reduced more */
1013 /* schedule next action */
1014 while (NULL == h->current)
1015 {
1016 h->current = h->action_head;
1017 if (NULL == h->current)
1018 {
1019 struct GNUNET_MessageHeader *hdr;
1020 struct GNUNET_MQ_Envelope *env;
1021
1022 if (GNUNET_YES != h->do_destroy)
1023 return; /* nothing to do */
1024 /* let service know that we're done */
1026 "Notifying service that we are done\n");
1027 h->do_destroy = GNUNET_SYSERR; /* in 'TEST' mode */
1028 env = GNUNET_MQ_msg (hdr,
1032 h);
1034 env);
1035 return;
1036 }
1037 GNUNET_CONTAINER_DLL_remove (h->action_head,
1038 h->action_tail,
1039 h->current);
1040 switch (h->current->type)
1041 {
1042 case ACTION_GET:
1043 transmit_get (h);
1044 break;
1045
1046 case ACTION_SET:
1047 case ACTION_UPDATE:
1048 transmit_set (h);
1049 break;
1050
1051 case ACTION_WATCH:
1052 transmit_watch (h);
1053 break;
1054
1055 default:
1056 GNUNET_assert (0);
1057 break;
1058 }
1059 }
1060}
1061
1062
1065 const char *subsystem,
1066 const char *name,
1069 void *cls)
1070{
1071 size_t slen1;
1072 size_t slen2;
1074
1075 if (NULL == handle)
1076 return NULL;
1077 GNUNET_assert (NULL != proc);
1078 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1079 if (NULL == subsystem)
1080 subsystem = "";
1081 if (NULL == name)
1082 name = "";
1083 slen1 = strlen (subsystem) + 1;
1084 slen2 = strlen (name) + 1;
1085 GNUNET_assert (slen1 + slen2 + sizeof(struct GNUNET_MessageHeader) <
1088 ai->sh = handle;
1089 ai->subsystem = GNUNET_strdup (subsystem);
1090 ai->name = GNUNET_strdup (name);
1091 ai->cont = cont;
1092 ai->proc = proc;
1093 ai->cls = cls;
1094 ai->type = ACTION_GET;
1095 ai->msize = slen1 + slen2 + sizeof(struct GNUNET_MessageHeader);
1097 handle->action_tail,
1098 ai);
1100 return ai;
1101}
1102
1103
1104void
1106{
1107 if (NULL == gh)
1108 return;
1109 gh->cont = NULL;
1110 if (gh->sh->current == gh)
1111 {
1112 gh->aborted = GNUNET_YES;
1113 return;
1114 }
1116 gh->sh->action_tail,
1117 gh);
1118 GNUNET_free (gh->name);
1119 GNUNET_free (gh->subsystem);
1120 GNUNET_free (gh);
1121}
1122
1123
1134int
1136 const char *subsystem,
1137 const char *name,
1139 void *proc_cls)
1140{
1142
1143 if (NULL == handle)
1144 return GNUNET_SYSERR;
1147 w->name = GNUNET_strdup (name);
1148 w->proc = proc;
1149 w->proc_cls = proc_cls;
1150 GNUNET_array_append (handle->watches,
1151 handle->watches_size,
1152 w);
1154 w);
1155 return GNUNET_OK;
1156}
1157
1158
1169int
1171 const char *subsystem,
1172 const char *name,
1174 void *proc_cls)
1175{
1177
1178 if (NULL == handle)
1179 return GNUNET_SYSERR;
1180 for (unsigned int i = 0; i < handle->watches_size; i++)
1181 {
1182 w = handle->watches[i];
1183 if (NULL == w)
1184 continue;
1185 if ((w->proc == proc) &&
1186 (w->proc_cls == proc_cls) &&
1187 (0 == strcmp (w->name,
1188 name)) &&
1189 (0 == strcmp (w->subsystem,
1190 subsystem)))
1191 {
1192 GNUNET_free (w->name);
1194 GNUNET_free (w);
1195 handle->watches[i] = NULL;
1196 return GNUNET_OK;
1197 }
1198 }
1199 return GNUNET_SYSERR;
1200}
1201
1202
1212static void
1214 const char *name,
1215 int make_persistent,
1216 uint64_t value,
1217 enum ActionType type)
1218{
1220 size_t slen;
1221 size_t nlen;
1222 size_t nsize;
1223 int64_t delta;
1224
1225 slen = strlen (h->subsystem) + 1;
1226 nlen = strlen (name) + 1;
1227 nsize = sizeof(struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1228 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
1229 {
1230 GNUNET_break (0);
1231 return;
1232 }
1233 for (ai = h->action_head; NULL != ai; ai = ai->next)
1234 {
1235 if (! ((0 == strcmp (ai->subsystem,
1236 h->subsystem)) &&
1237 (0 == strcmp (ai->name,
1238 name)) &&
1239 ((ACTION_UPDATE == ai->type) ||
1240 (ACTION_SET == ai->type))))
1241 continue;
1242 if (ACTION_SET == ai->type)
1243 {
1244 if (ACTION_UPDATE == type)
1245 {
1246 delta = (int64_t) value;
1247 if (delta > 0)
1248 {
1249 /* update old set by new delta */
1250 ai->value += delta;
1251 }
1252 else
1253 {
1254 /* update old set by new delta, but never go negative */
1255 if (ai->value < -delta)
1256 ai->value = 0;
1257 else
1258 ai->value += delta;
1259 }
1260 }
1261 else
1262 {
1263 /* new set overrides old set */
1264 ai->value = value;
1265 }
1266 }
1267 else
1268 {
1269 if (ACTION_UPDATE == type)
1270 {
1271 /* make delta cumulative */
1272 delta = (int64_t) value;
1273 ai->value += delta;
1274 }
1275 else
1276 {
1277 /* drop old 'update', use new 'set' instead */
1278 ai->value = value;
1279 ai->type = type;
1280 }
1281 }
1282 ai->timeout
1284 ai->make_persistent
1285 = make_persistent;
1286 return;
1287 }
1288 /* no existing entry matches, create a fresh one */
1290 ai->sh = h;
1291 ai->subsystem = GNUNET_strdup (h->subsystem);
1292 ai->name = GNUNET_strdup (name);
1294 ai->make_persistent = make_persistent;
1295 ai->msize = nsize;
1296 ai->value = value;
1297 ai->type = type;
1298 GNUNET_CONTAINER_DLL_insert_tail (h->action_head,
1299 h->action_tail,
1300 ai);
1302}
1303
1304
1305void
1307 const char *name,
1308 uint64_t value,
1309 int make_persistent)
1310{
1311 if (NULL == handle)
1312 return;
1313 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1315 name,
1316 make_persistent,
1317 value,
1318 ACTION_SET);
1319}
1320
1321
1322void
1324 const char *name,
1325 int64_t delta,
1326 int make_persistent)
1327{
1328 if (NULL == handle)
1329 return;
1330 if (0 == delta)
1331 return;
1332 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1334 name,
1335 make_persistent,
1336 (uint64_t) delta,
1338}
1339
1340
1341/* end of statistics_api.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static int watch
Watch value continuously.
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
static int do_disconnect
Option -D.
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition client.c:1060
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
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.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:293
GNUNET_MQ_Error
Error codes for the queue.
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.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition mq.c:655
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#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.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
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:1277
int(* GNUNET_STATISTICS_Iterator)(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STATISTICS_watch_cancel(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Stop watching statistics from the peer.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
void(* GNUNET_STATISTICS_Callback)(void *cls, int success)
Continuation called by GNUNET_STATISTICS_get() functions.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
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.
int GNUNET_STATISTICS_watch(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Watch statistics from the peer (be notified whenever they change).
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).
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
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
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
static int check_statistics_value(void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
ActionType
Types of actions.
@ ACTION_SET
Set a value.
@ ACTION_GET
Get a value.
@ ACTION_WATCH
Watch a value.
@ ACTION_UPDATE
Update a value.
static void reconnect_later(struct GNUNET_STATISTICS_Handle *h)
Reconnect at a later time, respecting back-off.
#define SET_TRANSMIT_TIMEOUT
How long do we wait until a statistics request for setting a value times out? (The update will be los...
static void transmit_watch(struct GNUNET_STATISTICS_Handle *handle)
Transmit a WATCH request (and if successful, start to receive the response).
static void handle_disconnect_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
Handle a GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM message.
static void handle_statistics_value(void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
static void schedule_watch_request(struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_WatchEntry *watch)
Transmit request to service that we want to watch the development of a particular value.
static void free_action_item(struct GNUNET_STATISTICS_GetHandle *gh)
Free memory associated with the given action item.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static void schedule_action(void *cls)
Schedule the next action to be performed.
static void handle_statistics_watch_value(void *cls, const struct GNUNET_STATISTICS_WatchValueMessage *wvm)
We have received a watch value from the service.
static int try_connect(struct GNUNET_STATISTICS_Handle *h)
Try to (re)connect to the statistics service.
static void transmit_get(struct GNUNET_STATISTICS_Handle *handle)
Transmit a GET request (and if successful, start to receive the response).
static void update_memory_statistics(struct GNUNET_STATISTICS_Handle *h)
Obtain statistics about this process's memory consumption and report those as well (if they changed).
static void do_destroy(void *cls)
Task used to destroy the statistics handle.
#define LOG(kind,...)
static void transmit_set(struct GNUNET_STATISTICS_Handle *handle)
Transmit a SET/UPDATE request.
static void add_setter_action(struct GNUNET_STATISTICS_Handle *h, const char *name, int make_persistent, uint64_t value, enum ActionType type)
Queue a request to change a statistic.
static void handle_statistics_end(void *cls, const struct GNUNET_MessageHeader *msg)
Handle a GNUNET_MESSAGE_TYPE_STATISTICS_END message.
static void reconnect_task(void *cls)
We've waited long enough, reconnect now.
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition arm_api.c:112
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Entry in list of pending tasks.
Definition scheduler.c:136
Linked list of things we still need to do.
char * name
What value is this action about? (can be NULL)
uint64_t value
Associated value.
GNUNET_STATISTICS_Callback cont
Continuation to call once action is complete.
int make_persistent
Flag for SET/UPDATE actions.
struct GNUNET_STATISTICS_GetHandle * prev
This is a doubly linked list.
GNUNET_STATISTICS_Iterator proc
Function to call (for GET actions only).
uint16_t msize
Size of the message that we will be transmitting.
enum ActionType type
Is this a ACTION_GET, ACTION_SET, ACTION_UPDATE or ACTION_WATCH?
struct GNUNET_TIME_Absolute timeout
Timeout for this action.
struct GNUNET_STATISTICS_GetHandle * next
This is a doubly linked list.
int aborted
Has the current iteration been aborted; for GET actions.
struct GNUNET_STATISTICS_Handle * sh
Main statistics handle.
char * subsystem
What subsystem is this action about? (can be NULL)
void * cls
Closure for proc and cont.
Handle for the service.
struct GNUNET_MQ_Handle * mq
Message queue to the service.
char * subsystem
Name of our subsystem.
struct GNUNET_STATISTICS_WatchEntry ** watches
Array of watch entries.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
struct GNUNET_STATISTICS_GetHandle * current
Action we are currently busy with (action request has been transmitted, we're now receiving the respo...
int do_destroy
Should this handle auto-destruct once all actions have been processed?
struct GNUNET_TIME_Relative backoff
Time for next connect retry.
unsigned int watches_size
Size of the watches array.
int receiving
Are we currently receiving from the service?
struct GNUNET_SCHEDULER_Task * destroy_task
Task for running do_destroy().
uint64_t peak_heap_size
Maximum heap size observed so far (if available).
struct GNUNET_STATISTICS_GetHandle * action_head
Head of the linked list of pending actions (first action to be performed).
struct GNUNET_SCHEDULER_Task * backoff_task
Task doing exponential back-off trying to reconnect.
struct GNUNET_STATISTICS_GetHandle * action_tail
Tail of the linked list of actions (for fast append).
uint64_t peak_rss
Maximum resident set side observed so far (if available).
Statistics message.
Definition statistics.h:41
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_STATISTICS_VALUE.
Definition statistics.h:45
uint32_t uid
Unique numerical identifier for the value (will not change during the same client-session).
Definition statistics.h:53
uint64_t value
The value.
Definition statistics.h:58
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
Entry kept for each value we are watching.
void * proc_cls
Closure for proc.
char * name
What value is this action about? (never NULL)
GNUNET_STATISTICS_Iterator proc
Function to call.
char * subsystem
What subsystem is this action about? (never NULL)
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
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_TRANSPORT_AddressIdentifier * next
Kept in a DLL.
struct GNUNET_MQ_Handle * mq
Connection to VPN service.
Definition vpn_api.c:44

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "statistics-api", __VA_ARGS__)

Definition at line 41 of file statistics_api.c.

Enumeration Type Documentation

◆ ActionType

enum ActionType

Types of actions.

Enumerator
ACTION_GET 

Get a value.

ACTION_SET 

Set a value.

ACTION_UPDATE 

Update a value.

ACTION_WATCH 

Watch a value.

Definition at line 46 of file statistics_api.c.

47{
52
57
62
67};

Function Documentation

◆ update_memory_statistics()

static void update_memory_statistics ( struct GNUNET_STATISTICS_Handle h)
static

Obtain statistics about this process's memory consumption and report those as well (if they changed).

Definition at line 265 of file statistics_api.c.

266{
267#if ENABLE_HEAP_STATISTICS
268 uint64_t current_heap_size = 0;
269 uint64_t current_rss = 0;
270
271 if (GNUNET_NO != h->do_destroy)
272 return;
273#if HAVE_MALLINFO2
274 {
275 struct mallinfo2 mi;
276
277 mi = mallinfo2 ();
278 current_heap_size = mi.uordblks + mi.fordblks;
279 }
280#endif
281#if HAVE_GETRUSAGE
282 {
283 struct rusage ru;
284
285 if (0 == getrusage (RUSAGE_SELF, &ru))
286 {
287 current_rss = 1024LL * ru.ru_maxrss;
288 }
289 }
290#endif
291 if (current_heap_size > h->peak_heap_size)
292 {
293 h->peak_heap_size = current_heap_size;
295 "# peak heap size",
296 current_heap_size,
297 GNUNET_NO);
298 }
299 if (current_rss > h->peak_rss)
300 {
301 h->peak_rss = current_rss;
303 "# peak resident set size",
304 current_rss,
305 GNUNET_NO);
306 }
307#endif
308}

References GNUNET_NO, GNUNET_STATISTICS_set(), and h.

Referenced by transmit_set().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconnect_later()

static void reconnect_later ( struct GNUNET_STATISTICS_Handle h)
static

Reconnect at a later time, respecting back-off.

Parameters
hstatistics handle

Definition at line 730 of file statistics_api.c.

731{
732 int loss;
734
735 GNUNET_assert (NULL == h->backoff_task);
736 if (GNUNET_YES == h->do_destroy)
737 {
738 /* So we are shutting down and the service is not reachable.
739 * Chances are that it's down for good and we are not going to connect to
740 * it anymore.
741 * Give up and don't sync the rest of the data.
742 */loss = GNUNET_NO;
743 for (gh = h->action_head; NULL != gh; gh = gh->next)
744 if ((gh->make_persistent) &&
745 (ACTION_SET == gh->type))
746 loss = GNUNET_YES;
747 if (GNUNET_YES == loss)
749 _ ("Could not save some persistent statistics\n"));
750 if (NULL != h->destroy_task)
751 GNUNET_SCHEDULER_cancel (h->destroy_task);
752 h->destroy_task = GNUNET_SCHEDULER_add_now (&do_destroy,
753 h);
754 return;
755 }
756 h->backoff_task
759 h);
760 h->backoff = GNUNET_TIME_STD_BACKOFF (h->backoff);
761}

References _, ACTION_SET, do_destroy(), GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, h, GNUNET_STATISTICS_GetHandle::make_persistent, GNUNET_STATISTICS_GetHandle::next, reconnect_task(), and GNUNET_STATISTICS_GetHandle::type.

Referenced by handle_disconnect_confirm(), handle_statistics_end(), handle_statistics_watch_value(), mq_error_handler(), and schedule_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_action()

static void schedule_action ( void *  cls)
static

Schedule the next action to be performed.

Parameters
clsstatistics handle to reconnect
clsstatistics handle

Definition at line 1001 of file statistics_api.c.

1002{
1003 struct GNUNET_STATISTICS_Handle *h = cls;
1004
1005 if (NULL != h->backoff_task)
1006 return; /* action already pending */
1007 if (GNUNET_YES != try_connect (h))
1008 {
1010 return;
1011 }
1012 if (0 < GNUNET_MQ_get_length (h->mq))
1013 return; /* Wait for queue to be reduced more */
1014 /* schedule next action */
1015 while (NULL == h->current)
1016 {
1017 h->current = h->action_head;
1018 if (NULL == h->current)
1019 {
1020 struct GNUNET_MessageHeader *hdr;
1021 struct GNUNET_MQ_Envelope *env;
1022
1023 if (GNUNET_YES != h->do_destroy)
1024 return; /* nothing to do */
1025 /* let service know that we're done */
1027 "Notifying service that we are done\n");
1028 h->do_destroy = GNUNET_SYSERR; /* in 'TEST' mode */
1029 env = GNUNET_MQ_msg (hdr,
1033 h);
1035 env);
1036 return;
1037 }
1038 GNUNET_CONTAINER_DLL_remove (h->action_head,
1039 h->action_tail,
1040 h->current);
1041 switch (h->current->type)
1042 {
1043 case ACTION_GET:
1044 transmit_get (h);
1045 break;
1046
1047 case ACTION_SET:
1048 case ACTION_UPDATE:
1049 transmit_set (h);
1050 break;
1051
1052 case ACTION_WATCH:
1053 transmit_watch (h);
1054 break;
1055
1056 default:
1057 GNUNET_assert (0);
1058 break;
1059 }
1060 }
1061}

References ACTION_GET, ACTION_SET, ACTION_UPDATE, ACTION_WATCH, env, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT, GNUNET_MQ_get_length(), GNUNET_MQ_msg, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_SYSERR, GNUNET_YES, h, GNUNET_ARM_Handle::mq, reconnect_later(), schedule_action(), transmit_get(), transmit_set(), transmit_watch(), and try_connect().

Referenced by add_setter_action(), GNUNET_STATISTICS_destroy(), GNUNET_STATISTICS_get(), handle_statistics_end(), reconnect_task(), schedule_action(), schedule_watch_request(), transmit_get(), transmit_set(), and transmit_watch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_watch_request()

static void schedule_watch_request ( struct GNUNET_STATISTICS_Handle h,
struct GNUNET_STATISTICS_WatchEntry watch 
)
static

Transmit request to service that we want to watch the development of a particular value.

Parameters
hstatistics handle
watchwatch entry of the value to watch

Definition at line 337 of file statistics_api.c.

339{
341 size_t slen;
342 size_t nlen;
343 size_t nsize;
344
345 slen = strlen (watch->subsystem) + 1;
346 nlen = strlen (watch->name) + 1;
347 nsize = sizeof(struct GNUNET_MessageHeader) + slen + nlen;
348 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
349 {
350 GNUNET_break (0);
351 return;
352 }
354 ai->sh = h;
355 ai->subsystem = GNUNET_strdup (watch->subsystem);
356 ai->name = GNUNET_strdup (watch->name);
358 ai->msize = nsize;
359 ai->type = ACTION_WATCH;
360 ai->proc = watch->proc;
361 ai->cls = watch->proc_cls;
363 h->action_tail,
364 ai);
366}

References ACTION_WATCH, ai, GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_MAX_MESSAGE_SIZE, GNUNET_new, GNUNET_strdup, GNUNET_TIME_UNIT_FOREVER_ABS, h, schedule_action(), and watch.

Referenced by GNUNET_STATISTICS_watch(), and try_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_action_item()

static void free_action_item ( struct GNUNET_STATISTICS_GetHandle gh)
static

Free memory associated with the given action item.

Parameters
ghaction item to free

Definition at line 375 of file statistics_api.c.

376{
378 GNUNET_free (gh->name);
379 GNUNET_free (gh);
380}

References GNUNET_free, GNUNET_STATISTICS_GetHandle::name, and GNUNET_STATISTICS_GetHandle::subsystem.

Referenced by do_disconnect(), GNUNET_STATISTICS_destroy(), handle_statistics_end(), transmit_set(), transmit_watch(), and try_connect().

Here is the caller graph for this function:

◆ do_disconnect()

static void do_disconnect ( struct GNUNET_STATISTICS_Handle h)
static

Disconnect from the statistics service.

Parameters
hstatistics handle to disconnect from

Definition at line 389 of file statistics_api.c.

390{
392
393 h->receiving = GNUNET_NO;
394 if (NULL != (c = h->current))
395 {
396 h->current = NULL;
397 if ((NULL != c->cont) &&
398 (GNUNET_YES != c->aborted))
399 {
400 c->cont (c->cls,
402 c->cont = NULL;
403 }
405 }
406 if (NULL != h->mq)
407 {
409 h->mq = NULL;
410 }
411}

References GNUNET_STATISTICS_GetHandle::aborted, GNUNET_STATISTICS_GetHandle::cls, GNUNET_STATISTICS_GetHandle::cont, free_action_item(), GNUNET_MQ_destroy(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, h, and GNUNET_ARM_Handle::mq.

Here is the call graph for this function:

◆ check_statistics_value()

static int check_statistics_value ( void *  cls,
const struct GNUNET_STATISTICS_ReplyMessage smsg 
)
static

Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.

Parameters
clsstatistics handle
smsgmessage received from the service, never NULL
Returns
GNUNET_OK if the message was well-formed

Definition at line 422 of file statistics_api.c.

424{
425 const char *service;
426 const char *name;
427 uint16_t size;
428
429 size = ntohs (smsg->header.size);
430 size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
431 if (size !=
432 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
433 size,
434 2,
435 &service,
436 &name))
437 {
438 GNUNET_break (0);
439 return GNUNET_SYSERR;
440 }
441 return GNUNET_OK;
442}

References GNUNET_break, GNUNET_OK, GNUNET_STRINGS_buffer_tokenize(), GNUNET_SYSERR, GNUNET_STATISTICS_ReplyMessage::header, name, service, GNUNET_MessageHeader::size, and size.

Here is the call graph for this function:

◆ handle_statistics_value()

static void handle_statistics_value ( void *  cls,
const struct GNUNET_STATISTICS_ReplyMessage smsg 
)
static

Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.

Parameters
clsstatistics handle
smsgmessage received from the service, never NULL
Returns
GNUNET_OK if the message was well-formed

Definition at line 453 of file statistics_api.c.

455{
456 struct GNUNET_STATISTICS_Handle *h = cls;
457 const char *service;
458 const char *name;
459 uint16_t size;
460
461 if (h->current->aborted)
462 return; /* iteration aborted, don't bother */
463
464 size = ntohs (smsg->header.size);
465 size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
467 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
468 size,
469 2,
470 &service,
471 &name));
473 "Received valid statistic on `%s:%s': %llu\n",
474 service, name,
475 (unsigned long long) GNUNET_ntohll (smsg->value));
476 if (GNUNET_OK !=
477 h->current->proc (h->current->cls,
478 service,
479 name,
480 GNUNET_ntohll (smsg->value),
481 (0 !=
482 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)) ))
483 {
485 "Processing of remaining statistics aborted by client.\n");
486 h->current->aborted = GNUNET_YES;
487 }
488}

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ntohll(), GNUNET_OK, GNUNET_STATISTICS_PERSIST_BIT, GNUNET_STRINGS_buffer_tokenize(), GNUNET_YES, h, GNUNET_STATISTICS_ReplyMessage::header, LOG, name, service, GNUNET_MessageHeader::size, size, GNUNET_STATISTICS_ReplyMessage::uid, and GNUNET_STATISTICS_ReplyMessage::value.

Here is the call graph for this function:

◆ handle_statistics_watch_value()

static void handle_statistics_watch_value ( void *  cls,
const struct GNUNET_STATISTICS_WatchValueMessage wvm 
)
static

We have received a watch value from the service.

Process it.

Parameters
clsstatistics handle
wvmthe watch value message

Definition at line 498 of file statistics_api.c.

501{
502 struct GNUNET_STATISTICS_Handle *h = cls;
504 uint32_t wid;
505
506 GNUNET_break (0 == ntohl (wvm->reserved));
507 wid = ntohl (wvm->wid);
508 if (wid >= h->watches_size)
509 {
512 return;
513 }
514 w = h->watches[wid];
515 if (NULL == w)
516 return;
517 (void) w->proc (w->proc_cls,
518 w->subsystem,
519 w->name,
520 GNUNET_ntohll (wvm->value),
521 0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
522}

References do_disconnect, GNUNET_STATISTICS_WatchValueMessage::flags, GNUNET_break, GNUNET_ntohll(), GNUNET_STATISTICS_PERSIST_BIT, h, GNUNET_STATISTICS_WatchEntry::name, GNUNET_STATISTICS_WatchEntry::proc, GNUNET_STATISTICS_WatchEntry::proc_cls, reconnect_later(), GNUNET_STATISTICS_WatchValueMessage::reserved, GNUNET_STATISTICS_WatchEntry::subsystem, GNUNET_STATISTICS_WatchValueMessage::value, and GNUNET_STATISTICS_WatchValueMessage::wid.

Here is the call graph for this function:

◆ mq_error_handler()

static void mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.

Not every message queue implementation supports an error handler.

Parameters
clsclosure with the struct GNUNET_STATISTICS_Handle *
errorerror code

Definition at line 534 of file statistics_api.c.

536{
537 struct GNUNET_STATISTICS_Handle *h = cls;
538
539 if (GNUNET_NO != h->do_destroy)
540 {
541 h->do_destroy = GNUNET_NO;
542 if (NULL != h->destroy_task)
543 {
544 GNUNET_SCHEDULER_cancel (h->destroy_task);
545 h->destroy_task = NULL;
546 }
548 GNUNET_NO);
549 return;
550 }
553}

References do_disconnect, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), h, and reconnect_later().

Referenced by try_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_destroy()

static void do_destroy ( void *  cls)
static

Task used to destroy the statistics handle.

Parameters
clsthe struct GNUNET_STATISTICS_Handle

Definition at line 562 of file statistics_api.c.

563{
564 struct GNUNET_STATISTICS_Handle *h = cls;
565
566 h->destroy_task = NULL;
567 h->do_destroy = GNUNET_NO;
569 "Running final destruction\n");
571 GNUNET_NO);
572}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_STATISTICS_destroy(), h, and LOG.

Referenced by GNUNET_STATISTICS_destroy(), handle_disconnect_confirm(), and reconnect_later().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_disconnect_confirm()

static void handle_disconnect_confirm ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle a GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM message.

We receive this message at the end of the shutdown when the service confirms that all data has been written to disk.

Parameters
clsour struct GNUNET_STATISTICS_Handle *
msgthe message

Definition at line 584 of file statistics_api.c.

586{
587 struct GNUNET_STATISTICS_Handle *h = cls;
588
589 if (GNUNET_SYSERR != h->do_destroy)
590 {
591 /* not in shutdown, why do we get 'TEST'? */
592 GNUNET_break (0);
595 return;
596 }
598 "Received DISCONNNECT_CONFIRM message from statistics, can complete disconnect\n");
599 if (NULL != h->destroy_task)
600 GNUNET_SCHEDULER_cancel (h->destroy_task);
601 h->destroy_task = GNUNET_SCHEDULER_add_now (&do_destroy,
602 h);
603}

References do_destroy(), do_disconnect, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, h, LOG, and reconnect_later().

Here is the call graph for this function:

◆ handle_statistics_end()

static void handle_statistics_end ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle a GNUNET_MESSAGE_TYPE_STATISTICS_END message.

We receive this message in response to a query to indicate that there are no further matching results.

Parameters
clsour struct GNUNET_STATISTICS_Handle *
msgthe message

Definition at line 615 of file statistics_api.c.

617{
618 struct GNUNET_STATISTICS_Handle *h = cls;
620
622 "Received end of statistics marker\n");
623 if (NULL == (c = h->current))
624 {
625 GNUNET_break (0);
628 return;
629 }
631 h->current = NULL;
633 if (NULL != c->cont)
634 {
635 c->cont (c->cls,
636 GNUNET_OK);
637 c->cont = NULL;
638 }
640}

References GNUNET_STATISTICS_GetHandle::cls, GNUNET_STATISTICS_GetHandle::cont, do_disconnect, free_action_item(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_OK, GNUNET_TIME_UNIT_MILLISECONDS, h, LOG, reconnect_later(), and schedule_action().

Here is the call graph for this function:

◆ try_connect()

static int try_connect ( struct GNUNET_STATISTICS_Handle h)
static

Try to (re)connect to the statistics service.

Parameters
hstatistics handle to reconnect
Returns
GNUNET_YES on success, GNUNET_NO on failure.

Definition at line 650 of file statistics_api.c.

651{
653 GNUNET_MQ_hd_fixed_size (disconnect_confirm,
656 h),
657 GNUNET_MQ_hd_fixed_size (statistics_end,
660 h),
661 GNUNET_MQ_hd_var_size (statistics_value,
664 h),
665 GNUNET_MQ_hd_fixed_size (statistics_watch_value,
668 h),
670 };
673
674 if (NULL != h->backoff_task)
675 return GNUNET_NO;
676 if (NULL != h->mq)
677 return GNUNET_YES;
679 "statistics",
680 handlers,
682 h);
683 if (NULL == h->mq)
684 {
686 "Failed to connect to statistics service!\n");
687 return GNUNET_NO;
688 }
689 gn = h->action_head;
690 while (NULL != (gh = gn))
691 {
692 gn = gh->next;
693 if (gh->type == ACTION_WATCH)
694 {
695 GNUNET_CONTAINER_DLL_remove (h->action_head,
696 h->action_tail,
697 gh);
698 free_action_item (gh);
699 }
700 }
701 for (unsigned int i = 0; i < h->watches_size; i++)
702 if (NULL != h->watches[i])
704 h->watches[i]);
705 return GNUNET_YES;
706}

References ACTION_WATCH, GNUNET_ARM_Handle::cfg, free_action_item(), GNUNET_CLIENT_connect(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM, GNUNET_MESSAGE_TYPE_STATISTICS_END, GNUNET_MESSAGE_TYPE_STATISTICS_VALUE, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_NO, GNUNET_YES, h, handlers, LOG, GNUNET_ARM_Handle::mq, mq_error_handler(), GNUNET_STATISTICS_GetHandle::next, schedule_watch_request(), and GNUNET_STATISTICS_GetHandle::type.

Referenced by schedule_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconnect_task()

static void reconnect_task ( void *  cls)
static

We've waited long enough, reconnect now.

Parameters
clsthe struct GNUNET_STATISTICS_Handle to reconnect

Definition at line 715 of file statistics_api.c.

716{
717 struct GNUNET_STATISTICS_Handle *h = cls;
718
719 h->backoff_task = NULL;
721}

References h, and schedule_action().

Referenced by reconnect_later().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_get()

static void transmit_get ( struct GNUNET_STATISTICS_Handle handle)
static

Transmit a GET request (and if successful, start to receive the response).

Parameters
handlestatistics handle

Definition at line 771 of file statistics_api.c.

772{
774 struct GNUNET_MessageHeader *hdr;
775 struct GNUNET_MQ_Envelope *env;
776 size_t slen1;
777 size_t slen2;
778
779 GNUNET_assert (NULL != (c = handle->current));
780 slen1 = strlen (c->subsystem) + 1;
781 slen2 = strlen (c->name) + 1;
783 slen1 + slen2,
785 GNUNET_assert (slen1 + slen2 ==
786 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
787 slen1 + slen2,
788 2,
789 c->subsystem,
790 c->name));
793 handle);
795 env);
796}

References env, GNUNET_assert, GNUNET_MESSAGE_TYPE_STATISTICS_GET, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_STRINGS_buffer_fill(), handle, GNUNET_VPN_Handle::mq, GNUNET_STATISTICS_GetHandle::name, schedule_action(), and GNUNET_STATISTICS_GetHandle::subsystem.

Referenced by schedule_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_watch()

static void transmit_watch ( struct GNUNET_STATISTICS_Handle handle)
static

Transmit a WATCH request (and if successful, start to receive the response).

Parameters
handlestatistics handle

Definition at line 806 of file statistics_api.c.

807{
808 struct GNUNET_MessageHeader *hdr;
809 struct GNUNET_MQ_Envelope *env;
810 size_t slen1;
811 size_t slen2;
812
814 "Transmitting watch request for `%s'\n",
815 handle->current->name);
816 slen1 = strlen (handle->current->subsystem) + 1;
817 slen2 = strlen (handle->current->name) + 1;
819 slen1 + slen2,
821 GNUNET_assert (slen1 + slen2 ==
822 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
823 slen1 + slen2,
824 2,
825 handle->current->subsystem,
826 handle->current->name));
829 handle);
831 env);
832 GNUNET_assert (NULL == handle->current->cont);
833 free_action_item (handle->current);
834 handle->current = NULL;
836}

References env, free_action_item(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_STRINGS_buffer_fill(), handle, LOG, GNUNET_VPN_Handle::mq, and schedule_action().

Referenced by schedule_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_set()

static void transmit_set ( struct GNUNET_STATISTICS_Handle handle)
static

Transmit a SET/UPDATE request.

Parameters
handlestatistics handle

Definition at line 845 of file statistics_api.c.

846{
848 struct GNUNET_MQ_Envelope *env;
849 size_t slen;
850 size_t nlen;
851
852 slen = strlen (handle->current->subsystem) + 1;
853 nlen = strlen (handle->current->name) + 1;
855 slen + nlen,
857 r->flags = 0;
858 r->value = GNUNET_htonll (handle->current->value);
859 if (handle->current->make_persistent)
861 if (handle->current->type == ACTION_UPDATE)
863 GNUNET_assert (slen + nlen ==
864 GNUNET_STRINGS_buffer_fill ((char *) &r[1],
865 slen + nlen,
866 2,
867 handle->current->subsystem,
868 handle->current->name));
869 GNUNET_assert (NULL == handle->current->cont);
870 free_action_item (handle->current);
871 handle->current = NULL;
875 handle);
877 env);
878}

References ACTION_UPDATE, env, GNUNET_STATISTICS_SetMessage::flags, free_action_item(), GNUNET_assert, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_STATISTICS_SET, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_STATISTICS_SETFLAG_PERSISTENT, GNUNET_STATISTICS_SETFLAG_RELATIVE, GNUNET_STRINGS_buffer_fill(), handle, GNUNET_VPN_Handle::mq, schedule_action(), update_memory_statistics(), and GNUNET_STATISTICS_SetMessage::value.

Referenced by schedule_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_setter_action()

static void add_setter_action ( struct GNUNET_STATISTICS_Handle h,
const char *  name,
int  make_persistent,
uint64_t  value,
enum ActionType  type 
)
static

Queue a request to change a statistic.

Parameters
hstatistics handle
namename of the value
make_persistentshould the value be kept across restarts?
valuenew value or change
typetype of the action (ACTION_SET or ACTION_UPDATE)

Definition at line 1214 of file statistics_api.c.

1219{
1221 size_t slen;
1222 size_t nlen;
1223 size_t nsize;
1224 int64_t delta;
1225
1226 slen = strlen (h->subsystem) + 1;
1227 nlen = strlen (name) + 1;
1228 nsize = sizeof(struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1229 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
1230 {
1231 GNUNET_break (0);
1232 return;
1233 }
1234 for (ai = h->action_head; NULL != ai; ai = ai->next)
1235 {
1236 if (! ((0 == strcmp (ai->subsystem,
1237 h->subsystem)) &&
1238 (0 == strcmp (ai->name,
1239 name)) &&
1240 ((ACTION_UPDATE == ai->type) ||
1241 (ACTION_SET == ai->type))))
1242 continue;
1243 if (ACTION_SET == ai->type)
1244 {
1245 if (ACTION_UPDATE == type)
1246 {
1247 delta = (int64_t) value;
1248 if (delta > 0)
1249 {
1250 /* update old set by new delta */
1251 ai->value += delta;
1252 }
1253 else
1254 {
1255 /* update old set by new delta, but never go negative */
1256 if (ai->value < -delta)
1257 ai->value = 0;
1258 else
1259 ai->value += delta;
1260 }
1261 }
1262 else
1263 {
1264 /* new set overrides old set */
1265 ai->value = value;
1266 }
1267 }
1268 else
1269 {
1270 if (ACTION_UPDATE == type)
1271 {
1272 /* make delta cumulative */
1273 delta = (int64_t) value;
1274 ai->value += delta;
1275 }
1276 else
1277 {
1278 /* drop old 'update', use new 'set' instead */
1279 ai->value = value;
1280 ai->type = type;
1281 }
1282 }
1283 ai->timeout
1285 ai->make_persistent
1286 = make_persistent;
1287 return;
1288 }
1289 /* no existing entry matches, create a fresh one */
1291 ai->sh = h;
1292 ai->subsystem = GNUNET_strdup (h->subsystem);
1293 ai->name = GNUNET_strdup (name);
1295 ai->make_persistent = make_persistent;
1296 ai->msize = nsize;
1297 ai->value = value;
1298 ai->type = type;
1299 GNUNET_CONTAINER_DLL_insert_tail (h->action_head,
1300 h->action_tail,
1301 ai);
1303}

References ACTION_SET, ACTION_UPDATE, ai, delta, GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_MAX_MESSAGE_SIZE, GNUNET_new, GNUNET_strdup, GNUNET_TIME_relative_to_absolute(), h, name, GNUNET_TRANSPORT_AddressIdentifier::next, schedule_action(), SET_TRANSMIT_TIMEOUT, type, and value.

Referenced by GNUNET_STATISTICS_set(), and GNUNET_STATISTICS_update().

Here is the call graph for this function:
Here is the caller graph for this function: