GNUnet 0.21.2
statistics_api.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 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_constants.h"
29#include "gnunet_protocols.h"
31#include "statistics.h"
32
38#define SET_TRANSMIT_TIMEOUT GNUNET_TIME_relative_multiply ( \
39 GNUNET_TIME_UNIT_SECONDS, 2)
40
41#define LOG(kind, ...) GNUNET_log_from (kind, "statistics-api", __VA_ARGS__)
42
47{
52
57
62
67};
68
69
74{
78 char *subsystem;
79
83 char *name;
84
89
93 void *proc_cls;
94};
95
96
101{
106
111
116
121
125 char *name;
126
131
136
140 void *cls;
141
146
150 uint64_t value;
151
156
161
166
170 uint16_t msize;
171};
172
173
178{
183
188
193
199
204
211
216
221
226
231
236
240 uint64_t peak_rss;
241
245 unsigned int watches_size;
246
252
257};
258
259
264static void
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}
309
310
316static void
318
319
325static void
326schedule_action (void *cls);
327
328
336static void
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}
367
368
374static void
376{
378 GNUNET_free (gh->name);
379 GNUNET_free (gh);
380}
381
382
388static void
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}
412
413
421static int
423 const struct GNUNET_STATISTICS_ReplyMessage *smsg)
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}
443
444
452static void
454 const struct GNUNET_STATISTICS_ReplyMessage *smsg)
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}
489
490
497static void
499 const struct
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}
523
524
533static void
535 enum GNUNET_MQ_Error error)
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}
554
555
561static void
562do_destroy (void *cls)
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}
573
574
583static void
585 const struct GNUNET_MessageHeader *msg)
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}
604
605
614static void
616 const struct GNUNET_MessageHeader *msg)
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}
641
642
649static int
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}
707
708
714static void
716{
717 struct GNUNET_STATISTICS_Handle *h = cls;
718
719 h->backoff_task = NULL;
721}
722
723
729static void
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}
762
763
770static void
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}
797
798
805static void
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}
837
838
844static void
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}
879
880
890 const struct GNUNET_CONFIGURATION_Handle *cfg)
891{
893
894 if (GNUNET_YES ==
896 "statistics",
897 "DISABLE"))
898 return NULL;
900 h->cfg = cfg;
901 h->subsystem = GNUNET_strdup (subsystem);
903 return h;
904}
905
906
915void
917 int sync_first)
918{
919 struct GNUNET_STATISTICS_GetHandle *pos;
921
922 if (NULL == h)
923 return;
924 GNUNET_assert (GNUNET_NO == h->do_destroy); /* Don't call twice. */
925 if ((sync_first) &&
926 (NULL != h->mq) &&
927 (0 != GNUNET_MQ_get_length (h->mq)))
928 {
929 if ((NULL != h->current) &&
930 (ACTION_GET == h->current->type))
931 h->current->aborted = GNUNET_YES;
932 next = h->action_head;
933 while (NULL != (pos = next))
934 {
935 next = pos->next;
936 if ((ACTION_GET == pos->type) ||
937 (ACTION_WATCH == pos->type))
938 {
939 GNUNET_CONTAINER_DLL_remove (h->action_head,
940 h->action_tail,
941 pos);
942 free_action_item (pos);
943 }
944 }
945 h->do_destroy = GNUNET_YES;
947 GNUNET_assert (NULL == h->destroy_task);
948 h->destroy_task
950 5),
951 &do_destroy,
952 h);
954 "Deferring destruction\n");
955 return; /* do not finish destruction just yet */
956 }
957 /* do clean up all */
959 "Cleaning all up\n");
960 while (NULL != (pos = h->action_head))
961 {
962 GNUNET_CONTAINER_DLL_remove (h->action_head,
963 h->action_tail,
964 pos);
965 free_action_item (pos);
966 }
968 if (NULL != h->backoff_task)
969 {
970 GNUNET_SCHEDULER_cancel (h->backoff_task);
971 h->backoff_task = NULL;
972 }
973 if (NULL != h->destroy_task)
974 {
975 GNUNET_break (0);
976 GNUNET_SCHEDULER_cancel (h->destroy_task);
977 h->destroy_task = NULL;
978 }
979 for (unsigned int i = 0; i < h->watches_size; i++)
980 {
981 if (NULL == h->watches[i])
982 continue;
983 GNUNET_free (h->watches[i]->subsystem);
984 GNUNET_free (h->watches[i]->name);
985 GNUNET_free (h->watches[i]);
986 }
987 GNUNET_array_grow (h->watches,
988 h->watches_size,
989 0);
990 GNUNET_free (h->subsystem);
991 GNUNET_free (h);
992}
993
994
1000static void
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}
1062
1063
1066 const char *subsystem,
1067 const char *name,
1070 void *cls)
1071{
1072 size_t slen1;
1073 size_t slen2;
1075
1076 if (NULL == handle)
1077 return NULL;
1078 GNUNET_assert (NULL != proc);
1079 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1080 if (NULL == subsystem)
1081 subsystem = "";
1082 if (NULL == name)
1083 name = "";
1084 slen1 = strlen (subsystem) + 1;
1085 slen2 = strlen (name) + 1;
1086 GNUNET_assert (slen1 + slen2 + sizeof(struct GNUNET_MessageHeader) <
1089 ai->sh = handle;
1090 ai->subsystem = GNUNET_strdup (subsystem);
1091 ai->name = GNUNET_strdup (name);
1092 ai->cont = cont;
1093 ai->proc = proc;
1094 ai->cls = cls;
1095 ai->type = ACTION_GET;
1096 ai->msize = slen1 + slen2 + sizeof(struct GNUNET_MessageHeader);
1098 handle->action_tail,
1099 ai);
1101 return ai;
1102}
1103
1104
1105void
1107{
1108 if (NULL == gh)
1109 return;
1110 gh->cont = NULL;
1111 if (gh->sh->current == gh)
1112 {
1113 gh->aborted = GNUNET_YES;
1114 return;
1115 }
1117 gh->sh->action_tail,
1118 gh);
1119 GNUNET_free (gh->name);
1120 GNUNET_free (gh->subsystem);
1121 GNUNET_free (gh);
1122}
1123
1124
1135int
1137 const char *subsystem,
1138 const char *name,
1140 void *proc_cls)
1141{
1143
1144 if (NULL == handle)
1145 return GNUNET_SYSERR;
1148 w->name = GNUNET_strdup (name);
1149 w->proc = proc;
1150 w->proc_cls = proc_cls;
1151 GNUNET_array_append (handle->watches,
1152 handle->watches_size,
1153 w);
1155 w);
1156 return GNUNET_OK;
1157}
1158
1159
1170int
1172 const char *subsystem,
1173 const char *name,
1175 void *proc_cls)
1176{
1178
1179 if (NULL == handle)
1180 return GNUNET_SYSERR;
1181 for (unsigned int i = 0; i < handle->watches_size; i++)
1182 {
1183 w = handle->watches[i];
1184 if (NULL == w)
1185 continue;
1186 if ((w->proc == proc) &&
1187 (w->proc_cls == proc_cls) &&
1188 (0 == strcmp (w->name,
1189 name)) &&
1190 (0 == strcmp (w->subsystem,
1191 subsystem)))
1192 {
1193 GNUNET_free (w->name);
1195 GNUNET_free (w);
1196 handle->watches[i] = NULL;
1197 return GNUNET_OK;
1198 }
1199 }
1200 return GNUNET_SYSERR;
1201}
1202
1203
1213static void
1215 const char *name,
1216 int make_persistent,
1217 uint64_t value,
1218 enum ActionType type)
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}
1304
1305
1306void
1308 const char *name,
1309 uint64_t value,
1310 int make_persistent)
1311{
1312 if (NULL == handle)
1313 return;
1314 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1316 name,
1317 make_persistent,
1318 value,
1319 ACTION_SET);
1320}
1321
1322
1323void
1325 const char *name,
1326 int64_t delta,
1327 int make_persistent)
1328{
1329 if (NULL == handle)
1330 return;
1331 if (0 == delta)
1332 return;
1333 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1335 name,
1336 make_persistent,
1337 (uint64_t) delta,
1339}
1340
1341
1342/* 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:99
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
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 struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition: gnunet-vpn.c:35
Constants for network protocols.
API to create, modify and access statistics.
#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:1057
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.
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
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:304
#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:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#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:638
#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:683
#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:981
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:1305
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:1278
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:72
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:44
#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
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:484
#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: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
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 do_disconnect(struct GNUNET_STATISTICS_Handle *h)
Disconnect from the statistics service.
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