GNUnet  0.10.x
Data Structures | Functions | Variables
gnunet-service-statistics.c File Reference

program that tracks statistics More...

#include "platform.h"
#include "gnunet_bio_lib.h"
#include "gnunet_container_lib.h"
#include "gnunet_disk_lib.h"
#include "gnunet_getopt_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_service_lib.h"
#include "gnunet_statistics_service.h"
#include "gnunet_strings_lib.h"
#include "gnunet_time_lib.h"
#include "statistics.h"
Include dependency graph for gnunet-service-statistics.c:

Go to the source code of this file.

Data Structures

struct  WatchEntry
 Watch entry. More...
 
struct  StatsEntry
 Entry in the statistics list. More...
 
struct  SubsystemEntry
 We keep the statistics organized by subsystem for faster lookup during SET operations. More...
 
struct  ClientEntry
 Information about one of our clients. More...
 

Functions

static void save ()
 Write persistent statistics to disk. More...
 
static void transmit (struct ClientEntry *ce, const struct StatsEntry *e)
 Transmit the given stats value. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static int check_get (void *cls, const struct GNUNET_MessageHeader *message)
 Check integrity of GET-message. More...
 
static void handle_get (void *cls, const struct GNUNET_MessageHeader *message)
 Handle GET-message. More...
 
static void notify_change (struct StatsEntry *se)
 Notify all clients listening about a change to a value. More...
 
static struct SubsystemEntryfind_subsystem_entry (struct ClientEntry *ce, const char *service)
 Find the subsystem entry of the given name for the specified client. More...
 
static struct StatsEntryfind_stat_entry (struct SubsystemEntry *se, const char *name)
 Find the statistics entry of the given subsystem. More...
 
static int check_set (void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
 Check format of SET-message. More...
 
static void handle_set (void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
 Handle SET-message. More...
 
static int check_watch (void *cls, const struct GNUNET_MessageHeader *message)
 Check integrity of WATCH-message. More...
 
static void handle_watch (void *cls, const struct GNUNET_MessageHeader *message)
 Handle WATCH-message. More...
 
static void handle_disconnect (void *cls, const struct GNUNET_MessageHeader *message)
 Handle DISCONNECT-message. More...
 
static void do_shutdown ()
 Actually perform the shutdown. More...
 
static void shutdown_task (void *cls)
 Task run during shutdown. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
 A client disconnected. More...
 
static int inject_message (void *cls, const struct GNUNET_MessageHeader *message)
 We've read a struct GNUNET_STATISTICS_SetMessage * from disk. More...
 
static void load ()
 Load persistent values from disk. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Process statistics requests. More...
 
 GNUNET_SERVICE_MAIN ("statistics", GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(set, GNUNET_MESSAGE_TYPE_STATISTICS_SET, struct GNUNET_STATISTICS_SetMessage, NULL), GNUNET_MQ_hd_var_size(get, GNUNET_MESSAGE_TYPE_STATISTICS_GET, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_var_size(watch, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(disconnect, GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration. More...
 
static struct SubsystemEntrysub_head
 Head of linked list of subsystems with active statistics. More...
 
static struct SubsystemEntrysub_tail
 Tail of linked list of subsystems with active statistics. More...
 
static unsigned int client_count
 Number of connected clients. More...
 
static struct GNUNET_NotificationContextnc
 Our notification context. More...
 
static uint32_t uidgen
 Counter used to generate unique values. More...
 
static int in_shutdown
 Set to GNUNET_YES if we are shutting down as soon as possible. More...
 

Detailed Description

program that tracks statistics

Author
Christian Grothoff

Definition in file gnunet-service-statistics.c.

Function Documentation

◆ save()

static void save ( )
static

Write persistent statistics to disk.

Definition at line 248 of file gnunet-service-statistics.c.

References _, fn, GNUNET_assert, GNUNET_BIO_write(), GNUNET_BIO_write_close(), GNUNET_BIO_write_open(), GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONTAINER_DLL_remove, GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_htonll(), GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_MESSAGE_TYPE_STATISTICS_SET, GNUNET_OK, GNUNET_STATISTICS_SETFLAG_PERSISTENT, GNUNET_STRINGS_buffer_fill(), GNUNET_STATISTICS_SetMessage::header, msg, StatsEntry::name, StatsEntry::persistent, SubsystemEntry::service, size, GNUNET_MessageHeader::size, SubsystemEntry::stat_head, SubsystemEntry::stat_tail, GNUNET_MessageHeader::type, UNLINK, StatsEntry::value, and wh.

Referenced by do_shutdown(), and GNUNET_STRINGS_parse_ipv6_policy().

249 {
250  struct SubsystemEntry *se;
251  struct StatsEntry *pos;
252  char *fn;
253  struct GNUNET_BIO_WriteHandle *wh;
254  uint16_t size;
255  unsigned long long total;
256  size_t nlen;
257  size_t slen;
259 
260  if (GNUNET_OK !=
262  "STATISTICS",
263  "DATABASE",
264  &fn))
265  {
267  "STATISTICS",
268  "DATABASE");
269  return;
270  }
272  wh = GNUNET_BIO_write_open (fn);
273  total = 0;
274  while (NULL != (se = sub_head))
275  {
277  sub_tail,
278  se);
279  slen = strlen (se->service) + 1;
280  while (NULL != (pos = se->stat_head))
281  {
283  se->stat_tail,
284  pos);
285  if ( (pos->persistent) &&
286  (NULL != wh) )
287  {
288  nlen = strlen (pos->name) + 1;
289  size = sizeof (struct GNUNET_STATISTICS_SetMessage) + nlen + slen;
290  GNUNET_assert (size < UINT16_MAX);
291  msg = GNUNET_malloc (size);
292 
293  msg->header.size = htons ((uint16_t) size);
295  GNUNET_assert (nlen + slen ==
296  GNUNET_STRINGS_buffer_fill ((char *) &msg[1],
297  nlen + slen,
298  2,
299  se->service,
300  pos->name));
301  msg->flags = htonl (pos->persistent ? GNUNET_STATISTICS_SETFLAG_PERSISTENT : 0);
302  msg->value = GNUNET_htonll (pos->value);
303  if (GNUNET_OK != GNUNET_BIO_write (wh,
304  msg,
305  size))
306  {
308  "write",
309  fn);
310  if (GNUNET_OK != GNUNET_BIO_write_close (wh))
312  "close",
313  fn);
314  wh = NULL;
315  }
316  else
317  {
318  total += size;
319  }
320  GNUNET_free (msg);
321  }
322  GNUNET_free (pos);
323  }
324  GNUNET_free (se);
325  }
326  if (NULL != wh)
327  {
328  if (GNUNET_OK !=
331  "close",
332  fn);
333  if (0 == total)
334  GNUNET_break (0 ==
335  UNLINK (fn));
336  else
338  _("Wrote %llu bytes of statistics to `%s'\n"),
339  total,
340  fn);
341  }
343 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
#define GNUNET_MESSAGE_TYPE_STATISTICS_SET
Set a statistical value.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
const char * service
Name of the subsystem this entry is for, allocated at the end of this struct, do not free()...
uint64_t value
Our value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
Message to set a statistic.
Definition: statistics.h:92
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
We keep the statistics organized by subsystem for faster lookup during SET operations.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static struct SubsystemEntry * sub_tail
Tail of linked list of subsystems with active statistics.
static char * fn
Filename of the unique file.
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:64
int persistent
Is this value persistent?
Handle for buffered writing.
Definition: bio.c:399
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
static unsigned int size
Size of the "table".
Definition: peer.c:67
Entry in the statistics list.
static struct GNUNET_TESTBED_BarrierWaitHandle * wh
Our barrier wait handle.
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h)
Close an open file for writing.
Definition: bio.c:457
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:103
struct StatsEntry * stat_tail
Tail of list of values kept for this subsystem.
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:430
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_STATISTICS_SET.
Definition: statistics.h:97
#define GNUNET_log(kind,...)
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
int GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: bio.c:505
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define GNUNET_malloc(size)
Wrapper around malloc.
#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:84
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit()

static void transmit ( struct ClientEntry ce,
const struct StatsEntry e 
)
static

Transmit the given stats value.

Parameters
clientreceiver of the value
evalue to transmit

Definition at line 353 of file gnunet-service-statistics.c.

References env, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_MESSAGE_TYPE_STATISTICS_VALUE, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_STATISTICS_PERSIST_BIT, GNUNET_STRINGS_buffer_fill(), m, ClientEntry::mq, StatsEntry::name, StatsEntry::persistent, SubsystemEntry::service, size, StatsEntry::subsystem, GNUNET_STATISTICS_ReplyMessage::uid, StatsEntry::uid, GNUNET_STATISTICS_ReplyMessage::value, and StatsEntry::value.

Referenced by handle_get().

355 {
356  struct GNUNET_MQ_Envelope *env;
358  size_t size;
359 
360  size = strlen (e->subsystem->service) + 1 +
361  strlen (e->name) + 1;
363  env = GNUNET_MQ_msg_extra (m,
364  size,
366  m->uid = htonl (e->uid);
367  if (e->persistent)
368  m->uid |= htonl (GNUNET_STATISTICS_PERSIST_BIT);
369  m->value = GNUNET_htonll (e->value);
370  GNUNET_assert (size ==
371  GNUNET_STRINGS_buffer_fill ((char *) &m[1],
372  size,
373  2,
374  e->subsystem->service,
375  e->name));
377  "Transmitting value for `%s:%s' (%d): %llu\n",
378  e->subsystem->service,
379  e->name,
380  e->persistent,
381  (unsigned long long) e->value);
382  GNUNET_MQ_send (ce->mq,
383  env);
384 }
const char * service
Name of the subsystem this entry is for, allocated at the end of this struct, do not free()...
uint64_t value
Our value.
Statistics message.
Definition: statistics.h:40
uint32_t uid
Unique numerical identifier for the value (will not change during the same client-session).
Definition: statistics.h:53
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
Response to a STATISTICS_GET message (with value).
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
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:64
int persistent
Is this value persistent?
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
#define GNUNET_STATISTICS_PERSIST_BIT
Flag for the struct GNUNET_STATISTICS_ReplyMessage UID only.
Definition: statistics.h:66
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_log(kind,...)
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:353
uint32_t uid
Unique ID.
struct SubsystemEntry * subsystem
Subsystem this entry belongs to.
uint64_t value
The value.
Definition: statistics.h:58
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
c

Definition at line 396 of file gnunet-service-statistics.c.

References WatchEntry::ce, ClientEntry::client, client_count, GNUNET_new, GNUNET_notification_context_add(), mq, and ClientEntry::mq.

Referenced by run().

399 {
400  struct ClientEntry *ce;
401 
402  ce = GNUNET_new (struct ClientEntry);
403  ce->client = c;
404  ce->mq = mq;
405  client_count++;
407  mq);
408  return ce;
409 }
static unsigned int client_count
Number of connected clients.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:164
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
Information about one of our clients.
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
static struct GNUNET_NotificationContext * nc
Our notification context.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_get()

static int check_get ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Check integrity of GET-message.

Parameters
clsidentification of the client
messagethe actual message
Returns
GNUNET_OK if message is well-formed

Definition at line 420 of file gnunet-service-statistics.c.

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

422 {
423  const char *service;
424  const char *name;
425  size_t size;
426 
427  size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
428  if (size !=
429  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
430  size,
431  2,
432  &service,
433  &name))
434  {
435  GNUNET_break (0);
436  return GNUNET_SYSERR;
437  }
438  return GNUNET_OK;
439 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:136
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
const char * name
Header for all communications.
Here is the call graph for this function:

◆ handle_get()

static void handle_get ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Handle GET-message.

Parameters
clsidentification of the client
messagethe actual message

Definition at line 449 of file gnunet-service-statistics.c.

References WatchEntry::ce, ClientEntry::client, end, env, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_STATISTICS_END, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_STRINGS_buffer_tokenize(), ClientEntry::mq, StatsEntry::name, name, StatsEntry::next, SubsystemEntry::next, SubsystemEntry::service, service, size, GNUNET_MessageHeader::size, SubsystemEntry::stat_head, and transmit().

451 {
452  struct ClientEntry *ce = cls;
453  struct GNUNET_MQ_Envelope *env;
454  struct GNUNET_MessageHeader *end;
455  const char *service;
456  const char *name;
457  size_t slen;
458  size_t nlen;
459  struct SubsystemEntry *se;
460  struct StatsEntry *pos;
461  size_t size;
462 
463  size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
464  GNUNET_assert (size ==
465  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
466  size,
467  2,
468  &service,
469  &name));
470  slen = strlen (service);
471  nlen = strlen (name);
473  "Received request for statistics on `%s:%s'\n",
474  slen ? service : "*",
475  nlen ? name : "*");
476  for (se = sub_head; NULL != se; se = se->next)
477  {
478  if (! ( (0 == slen) ||
479  (0 == strcmp (service, se->service))) )
480  continue;
481  for (pos = se->stat_head; NULL != pos; pos = pos->next)
482  {
483  if (! ( (0 == nlen) ||
484  (0 == strcmp (name,
485  pos->name))) )
486  continue;
487  transmit (ce,
488  pos);
489  }
490  }
491  env = GNUNET_MQ_msg (end,
493  GNUNET_MQ_send (ce->mq,
494  env);
496 }
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
const char * service
Name of the subsystem this entry is for, allocated at the end of this struct, do not free()...
#define GNUNET_MESSAGE_TYPE_STATISTICS_END
Response to a STATISTICS_GET message (end of value stream).
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct StatsEntry * next
This is a linked list.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
struct SubsystemEntry * next
Subsystems are kept in a DLL.
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:136
We keep the statistics organized by subsystem for faster lookup during SET operations.
Information about one of our clients.
static void transmit(struct ClientEntry *ce, const struct StatsEntry *e)
Transmit the given stats value.
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
const char * name
Entry in the statistics list.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
#define GNUNET_log(kind,...)
Header for all communications.
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:353
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
Here is the call graph for this function:

◆ notify_change()

static void notify_change ( struct StatsEntry se)
static

Notify all clients listening about a change to a value.

Parameters
sevalue that changed

Definition at line 505 of file gnunet-service-statistics.c.

References WatchEntry::ce, env, GNUNET_STATISTICS_WatchValueMessage::flags, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_STATISTICS_SETFLAG_PERSISTENT, GNUNET_YES, WatchEntry::last_value, WatchEntry::last_value_set, ClientEntry::mq, WatchEntry::next, StatsEntry::persistent, GNUNET_STATISTICS_WatchValueMessage::reserved, StatsEntry::value, GNUNET_STATISTICS_WatchValueMessage::value, StatsEntry::we_head, WatchEntry::wid, and GNUNET_STATISTICS_WatchValueMessage::wid.

Referenced by handle_set(), and handle_watch().

506 {
507  struct GNUNET_MQ_Envelope *env;
509  struct WatchEntry *pos;
510 
511  for (pos = se->we_head; NULL != pos; pos = pos->next)
512  {
513  if (GNUNET_YES == pos->last_value_set)
514  {
515  if (pos->last_value == se->value)
516  continue;
517  }
518  else
519  {
520  pos->last_value_set = GNUNET_YES;
521  }
522  env = GNUNET_MQ_msg (wvm,
524  wvm->flags = htonl (se->persistent ? GNUNET_STATISTICS_SETFLAG_PERSISTENT : 0);
525  wvm->wid = htonl (pos->wid);
526  wvm->reserved = htonl (0);
527  wvm->value = GNUNET_htonll (se->value);
528  GNUNET_MQ_send (pos->ce->mq,
529  env);
530  pos->last_value = se->value;
531  }
532 }
uint64_t value
Our value.
struct WatchEntry * we_head
Watch context for changes to this value, or NULL for none.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:128
uint32_t reserved
Reserved (always 0).
Definition: statistics.h:141
Message transmitted if a watched value changes.
Definition: statistics.h:117
uint32_t wid
Unique watch number for this client and this watched value.
int last_value_set
Is last_value valid GNUNET_NO : last_value is n/a, GNUNET_YES: last_value is valid.
#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE
Changes to a watched value.
int persistent
Is this value persistent?
uint32_t wid
Unique watch identification number (watch requests are enumerated in the order they are received...
Definition: statistics.h:136
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
uint64_t last_value
Last value we communicated to the client for this watch entry.
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct ClientEntry * ce
For which client is this watch entry?
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct WatchEntry * next
Watch entries are kept in a linked list.
#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:84
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_subsystem_entry()

static struct SubsystemEntry* find_subsystem_entry ( struct ClientEntry ce,
const char *  service 
)
static

Find the subsystem entry of the given name for the specified client.

Parameters
ceclient looking for the subsystem, may contain a hint to find the entry faster, can be NULL
servicename of the subsystem to look for
Returns
subsystem entry, never NULL (subsystem entry is created if necessary)

Definition at line 544 of file gnunet-service-statistics.c.

References GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, SubsystemEntry::next, SubsystemEntry::service, and ClientEntry::subsystem.

Referenced by handle_set(), and handle_watch().

546 {
547  size_t slen;
548  struct SubsystemEntry *se;
549 
550  if (NULL != ce)
551  se = ce->subsystem;
552  else
553  se = NULL;
554  if ( (NULL == se) ||
555  (0 != strcmp (service,
556  se->service)) )
557  {
558  for (se = sub_head; NULL != se; se = se->next)
559  if (0 == strcmp (service,
560  se->service))
561  break;
562  if (NULL != ce)
563  ce->subsystem = se;
564  }
565  if (NULL != se)
566  return se;
568  "Allocating new subsystem entry `%s'\n",
569  service);
570  slen = strlen (service) + 1;
571  se = GNUNET_malloc (sizeof (struct SubsystemEntry) +
572  slen);
573  GNUNET_memcpy (&se[1],
574  service,
575  slen);
576  se->service = (const char *) &se[1];
578  sub_tail,
579  se);
580  if (NULL != ce)
581  ce->subsystem = se;
582  return se;
583 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
const char * service
Name of the subsystem this entry is for, allocated at the end of this struct, do not free()...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct SubsystemEntry * subsystem
Which subsystem is this client writing to (SET/UPDATE)?
struct SubsystemEntry * next
Subsystems are kept in a DLL.
We keep the statistics organized by subsystem for faster lookup during SET operations.
#define GNUNET_memcpy(dst, src, n)
static struct SubsystemEntry * sub_tail
Tail of linked list of subsystems with active statistics.
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
#define GNUNET_log(kind,...)
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the caller graph for this function:

◆ find_stat_entry()

static struct StatsEntry* find_stat_entry ( struct SubsystemEntry se,
const char *  name 
)
static

Find the statistics entry of the given subsystem.

Parameters
subsystemsubsystem to look in
namename of the entry to look for
Returns
statistis entry, or NULL if not found

Definition at line 594 of file gnunet-service-statistics.c.

References StatsEntry::name, StatsEntry::next, and SubsystemEntry::stat_head.

Referenced by handle_set(), and handle_watch().

596 {
597  struct StatsEntry *pos;
598 
599  for (pos = se->stat_head; NULL != pos; pos = pos->next)
600  if (0 == strcmp (name, pos->name))
601  return pos;
602  return NULL;
603 }
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
struct StatsEntry * next
This is a linked list.
const char * name
Entry in the statistics list.
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
Here is the caller graph for this function:

◆ check_set()

static int check_set ( void *  cls,
const struct GNUNET_STATISTICS_SetMessage msg 
)
static

Check format of SET-message.

Parameters
clsthe struct ClientEntry
messagethe actual message
Returns
GNUNET_OK if message is well-formed

Definition at line 614 of file gnunet-service-statistics.c.

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

Referenced by inject_message().

616 {
617  const char *service;
618  const char *name;
619  size_t msize;
620 
621  msize = ntohs (msg->header.size) - sizeof (*msg);
622  if (msize !=
623  GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
624  msize,
625  2,
626  &service,
627  &name))
628  {
629  GNUNET_break (0);
630  return GNUNET_SYSERR;
631  }
632  return GNUNET_OK;
633 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:136
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
const char * name
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_STATISTICS_SET.
Definition: statistics.h:97
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_set()

static void handle_set ( void *  cls,
const struct GNUNET_STATISTICS_SetMessage msg 
)
static

Handle SET-message.

Parameters
clsthe struct ClientEntry
messagethe actual message

Definition at line 643 of file gnunet-service-statistics.c.

References WatchEntry::ce, ClientEntry::client, delta, find_stat_entry(), find_subsystem_entry(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_ntohll(), GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_SETFLAG_PERSISTENT, GNUNET_STATISTICS_SETFLAG_RELATIVE, GNUNET_STRINGS_buffer_tokenize(), GNUNET_YES, GNUNET_STATISTICS_SetMessage::header, StatsEntry::name, name, notify_change(), StatsEntry::persistent, service, StatsEntry::set, size, GNUNET_MessageHeader::size, SubsystemEntry::stat_head, SubsystemEntry::stat_tail, StatsEntry::subsystem, StatsEntry::uid, uidgen, StatsEntry::value, and value.

Referenced by inject_message().

645 {
646  struct ClientEntry *ce = cls;
647  const char *service;
648  const char *name;
649  size_t nlen;
650  uint16_t msize;
651  uint16_t size;
652  struct SubsystemEntry *se;
653  struct StatsEntry *pos;
654  uint32_t flags;
655  uint64_t value;
656  int64_t delta;
657  int changed;
658  int initial_set;
659 
660  msize = ntohs (msg->header.size);
661  size = msize - sizeof (struct GNUNET_STATISTICS_SetMessage);
662  GNUNET_assert (size ==
663  GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
664  size,
665  2,
666  &service,
667  &name));
668  se = find_subsystem_entry (ce,
669  service);
670  flags = ntohl (msg->flags);
671  value = GNUNET_ntohll (msg->value);
673  "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
674  service,
675  name,
676  (unsigned int) flags,
677  (unsigned long long) value);
678  pos = find_stat_entry (se,
679  name);
680  if (NULL != pos)
681  {
682  initial_set = 0;
683  if (0 == (flags & GNUNET_STATISTICS_SETFLAG_RELATIVE))
684  {
685  changed = (pos->value != value);
686  pos->value = value;
687  }
688  else
689  {
690  delta = (int64_t) value;
691  if ((delta < 0) && (pos->value < -delta))
692  {
693  changed = (0 != pos->value);
694  pos->value = 0;
695  }
696  else
697  {
698  changed = (0 != delta);
699  GNUNET_break ( (delta <= 0) ||
700  (pos->value + delta > pos->value) );
701  pos->value += delta;
702  }
703  }
704  if (GNUNET_NO == pos->set)
705  {
706  pos->set = GNUNET_YES;
707  initial_set = 1;
708  }
709  pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
710  if (pos != se->stat_head)
711  {
712  /* move to front for faster setting next time! */
714  se->stat_tail,
715  pos);
717  se->stat_tail,
718  pos);
719  }
721  "Statistic `%s:%s' updated to value %llu (%d).\n",
722  service,
723  name,
724  (unsigned long long) pos->value,
725  pos->persistent);
726  if ( (changed) ||
727  (1 == initial_set) )
728  notify_change (pos);
730  return;
731  }
732  /* not found, create a new entry */
733  nlen = strlen (name) + 1;
734  pos = GNUNET_malloc (sizeof (struct StatsEntry) + nlen);
735  GNUNET_memcpy (&pos[1],
736  name,
737  nlen);
738  pos->name = (const char *) &pos[1];
739  pos->subsystem = se;
740  if ( (0 == (flags & GNUNET_STATISTICS_SETFLAG_RELATIVE)) ||
741  (0 < (int64_t) GNUNET_ntohll (msg->value)) )
742  {
743  pos->value = GNUNET_ntohll (msg->value);
744  pos->set = GNUNET_YES;
745  }
746  else
747  {
748  pos->set = GNUNET_NO;
749  }
750  pos->uid = uidgen++;
751  pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
753  se->stat_tail,
754  pos);
756  "New statistic on `%s:%s' with value %llu created.\n",
757  service,
758  name,
759  (unsigned long long) pos->value);
760  if (NULL != ce)
762 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint64_t value
Our value.
static void notify_change(struct StatsEntry *se)
Notify all clients listening about a change to a value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
Message to set a statistic.
Definition: statistics.h:92
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_STATISTICS_SETFLAG_RELATIVE
The value being set is a relative change.
Definition: statistics.h:76
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:136
We keep the statistics organized by subsystem for faster lookup during SET operations.
#define GNUNET_memcpy(dst, src, n)
static char * value
Value of the record to add/remove.
Information about one of our clients.
int persistent
Is this value persistent?
static unsigned int size
Size of the "table".
Definition: peer.c:67
static uint32_t uidgen
Counter used to generate unique values.
const char * name
Entry in the statistics list.
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
int set
Is this value set? GNUNET_NO: value is n/a, GNUNET_YES: value is valid.
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:103
struct StatsEntry * stat_tail
Tail of list of values kept for this subsystem.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_STATISTICS_SET.
Definition: statistics.h:97
#define GNUNET_log(kind,...)
static struct StatsEntry * find_stat_entry(struct SubsystemEntry *se, const char *name)
Find the statistics entry of the given subsystem.
#define GNUNET_YES
Definition: gnunet_common.h:80
uint32_t uid
Unique ID.
struct SubsystemEntry * subsystem
Subsystem this entry belongs to.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#define GNUNET_malloc(size)
Wrapper around malloc.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#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:84
static struct SubsystemEntry * find_subsystem_entry(struct ClientEntry *ce, const char *service)
Find the subsystem entry of the given name for the specified client.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_watch()

static int check_watch ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Check integrity of WATCH-message.

Parameters
clsthe struct ClientEntry *
messagethe actual message
Returns
GNUNET_OK if message is well-formed

Definition at line 773 of file gnunet-service-statistics.c.

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

775 {
776  size_t size;
777  const char *service;
778  const char *name;
779 
780  size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
781  if (size !=
782  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
783  size,
784  2,
785  &service,
786  &name))
787  {
788  GNUNET_break (0);
789  return GNUNET_SYSERR;
790  }
791  return GNUNET_OK;
792 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:136
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
const char * name
Header for all communications.
Here is the call graph for this function:

◆ handle_watch()

static void handle_watch ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Handle WATCH-message.

Parameters
clsthe struct ClientEntry *
messagethe actual message

Definition at line 802 of file gnunet-service-statistics.c.

References WatchEntry::ce, ClientEntry::client, find_stat_entry(), find_subsystem_entry(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SERVICE_client_mark_monitor(), GNUNET_STRINGS_buffer_tokenize(), WatchEntry::last_value_set, ClientEntry::max_wid, StatsEntry::name, name, notify_change(), service, StatsEntry::set, size, GNUNET_MessageHeader::size, SubsystemEntry::stat_head, SubsystemEntry::stat_tail, StatsEntry::subsystem, StatsEntry::uid, uidgen, StatsEntry::value, StatsEntry::we_head, StatsEntry::we_tail, and WatchEntry::wid.

804 {
805  struct ClientEntry *ce = cls;
806  const char *service;
807  const char *name;
808  uint16_t msize;
809  uint16_t size;
810  struct SubsystemEntry *se;
811  struct StatsEntry *pos;
812  struct WatchEntry *we;
813  size_t nlen;
814 
815  if (NULL == nc)
816  {
818  return;
819  }
821  msize = ntohs (message->size);
822  size = msize - sizeof (struct GNUNET_MessageHeader);
823  GNUNET_assert (size ==
824  GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
825  size,
826  2,
827  &service,
828  &name));
830  "Received request to watch statistic on `%s:%s'\n",
831  service,
832  name);
833  se = find_subsystem_entry (ce,
834  service);
835  pos = find_stat_entry (se,
836  name);
837  if (NULL == pos)
838  {
839  nlen = strlen (name) + 1;
840  pos = GNUNET_malloc (sizeof (struct StatsEntry) +
841  nlen);
842  GNUNET_memcpy (&pos[1],
843  name,
844  nlen);
845  pos->name = (const char *) &pos[1];
846  pos->subsystem = se;
848  se->stat_tail,
849  pos);
850  pos->uid = uidgen++;
851  pos->set = GNUNET_NO;
853  "New statistic on `%s:%s' with value %llu created.\n",
854  service,
855  name,
856  (unsigned long long) pos->value);
857  }
858  we = GNUNET_new (struct WatchEntry);
859  we->ce = ce;
861  we->wid = ce->max_wid++;
863  pos->we_tail,
864  we);
865  if (0 != pos->value)
866  notify_change (pos);
868 }
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint64_t value
Our value.
static void notify_change(struct StatsEntry *se)
Notify all clients listening about a change to a value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct WatchEntry * we_head
Watch context for changes to this value, or NULL for none.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
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:136
struct WatchEntry * we_tail
Watch context for changes to this value, or NULL for none.
We keep the statistics organized by subsystem for faster lookup during SET operations.
#define GNUNET_memcpy(dst, src, n)
uint32_t wid
Unique watch number for this client and this watched value.
Information about one of our clients.
int last_value_set
Is last_value valid GNUNET_NO : last_value is n/a, GNUNET_YES: last_value is valid.
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2704
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
static unsigned int size
Size of the "table".
Definition: peer.c:67
static uint32_t uidgen
Counter used to generate unique values.
const char * name
Entry in the statistics list.
struct ClientEntry * ce
For which client is this watch entry?
const char * name
Name for the value stored by this entry, allocated at the end of this struct.
int set
Is this value set? GNUNET_NO: value is n/a, GNUNET_YES: value is valid.
static struct GNUNET_NotificationContext * nc
Our notification context.
struct StatsEntry * stat_tail
Tail of list of values kept for this subsystem.
#define GNUNET_log(kind,...)
static struct StatsEntry * find_stat_entry(struct SubsystemEntry *se, const char *name)
Find the statistics entry of the given subsystem.
Header for all communications.
uint32_t uid
Unique ID.
struct SubsystemEntry * subsystem
Subsystem this entry belongs to.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
uint32_t max_wid
Maximum watch ID used by this client so far.
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct SubsystemEntry * find_subsystem_entry(struct ClientEntry *ce, const char *service)
Find the subsystem entry of the given name for the specified client.
Here is the call graph for this function:

◆ handle_disconnect()

static void handle_disconnect ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Handle DISCONNECT-message.

Sync to disk and send back a GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM message.

Parameters
clsthe struct ClientEntry *
messagethe actual message

Definition at line 880 of file gnunet-service-statistics.c.

References WatchEntry::ce, ClientEntry::client, env, GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), ClientEntry::mq, and msg.

882 {
883  struct ClientEntry *ce = cls;
884  struct GNUNET_MQ_Envelope *env;
885  struct GNUNET_MessageHeader *msg;
886 
887  env = GNUNET_MQ_msg (msg,
889  GNUNET_MQ_send (ce->mq,
890  env);
892 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
Service confirms disconnect and that it is done processing all requests from the client.
Information about one of our clients.
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Header for all communications.
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:353
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
Here is the call graph for this function:

◆ do_shutdown()

static void do_shutdown ( )
static

Actually perform the shutdown.

Definition at line 899 of file gnunet-service-statistics.c.

References client_count, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_notification_context_destroy(), save(), SubsystemEntry::stat_head, SubsystemEntry::stat_tail, StatsEntry::we_head, and StatsEntry::we_tail.

Referenced by client_disconnect_cb(), and shutdown_task().

900 {
901  struct WatchEntry *we;
902  struct StatsEntry *pos;
903  struct SubsystemEntry *se;
904 
905  if (NULL == nc)
906  return;
907  save ();
909  nc = NULL;
911  while (NULL != (se = sub_head))
912  {
914  sub_tail,
915  se);
916  while (NULL != (pos = se->stat_head))
917  {
919  se->stat_tail,
920  pos);
921  while (NULL != (we = pos->we_head))
922  {
923  GNUNET_break (0);
925  pos->we_tail,
926  we);
927  GNUNET_free (we);
928  }
929  GNUNET_free (pos);
930  }
931  GNUNET_free (se);
932  }
933 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
static unsigned int client_count
Number of connected clients.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct WatchEntry * we_head
Watch context for changes to this value, or NULL for none.
static void save()
Write persistent statistics to disk.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct WatchEntry * we_tail
Watch context for changes to this value, or NULL for none.
We keep the statistics organized by subsystem for faster lookup during SET operations.
static struct SubsystemEntry * sub_tail
Tail of linked list of subsystems with active statistics.
Entry in the statistics list.
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
static struct GNUNET_NotificationContext * nc
Our notification context.
struct StatsEntry * stat_tail
Tail of list of values kept for this subsystem.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:141
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsunused

Definition at line 942 of file gnunet-service-statistics.c.

References client_count, do_shutdown(), GNUNET_YES, and in_shutdown.

Referenced by run().

943 {
945  if (0 != client_count)
946  return;
947  do_shutdown ();
948 }
static unsigned int client_count
Number of connected clients.
static int in_shutdown
Set to GNUNET_YES if we are shutting down as soon as possible.
static void do_shutdown()
Actually perform the shutdown.
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  app_cls 
)
static

A client disconnected.

Remove all of its data structure entries.

Parameters
clsclosure, NULL
clientidentification of the client
app_clsthe struct ClientEntry *

Definition at line 959 of file gnunet-service-statistics.c.

References WatchEntry::ce, client_count, do_shutdown(), GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_YES, in_shutdown, WatchEntry::next, StatsEntry::next, SubsystemEntry::next, SubsystemEntry::stat_head, StatsEntry::we_head, and StatsEntry::we_tail.

Referenced by run().

962 {
963  struct ClientEntry *ce = app_cls;
964  struct WatchEntry *we;
965  struct WatchEntry *wen;
966  struct StatsEntry *pos;
967  struct SubsystemEntry *se;
968 
969  client_count--;
970  for (se = sub_head; NULL != se; se = se->next)
971  {
972  for (pos = se->stat_head; NULL != pos; pos = pos->next)
973  {
974  wen = pos->we_head;
975  while (NULL != (we = wen))
976  {
977  wen = we->next;
978  if (we->ce != ce)
979  continue;
981  pos->we_tail,
982  we);
983  GNUNET_free (we);
984  }
985  }
986  }
987  GNUNET_free (ce);
988  if ( (0 == client_count) &&
989  (GNUNET_YES == in_shutdown) )
990  do_shutdown ();
991 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StatsEntry * stat_head
Head of list of values kept for this subsystem.
static unsigned int client_count
Number of connected clients.
struct StatsEntry * next
This is a linked list.
struct WatchEntry * we_head
Watch context for changes to this value, or NULL for none.
static int in_shutdown
Set to GNUNET_YES if we are shutting down as soon as possible.
struct SubsystemEntry * next
Subsystems are kept in a DLL.
struct WatchEntry * we_tail
Watch context for changes to this value, or NULL for none.
We keep the statistics organized by subsystem for faster lookup during SET operations.
Information about one of our clients.
static void do_shutdown()
Actually perform the shutdown.
Entry in the statistics list.
struct ClientEntry * ce
For which client is this watch entry?
static struct SubsystemEntry * sub_head
Head of linked list of subsystems with active statistics.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct WatchEntry * next
Watch entries are kept in a linked list.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ inject_message()

static int inject_message ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

We've read a struct GNUNET_STATISTICS_SetMessage * from disk.

Check that it is well-formed, and if so pass it to the handler for set messages.

Parameters
clsNULL
messagethe message found on disk
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 1006 of file gnunet-service-statistics.c.

References check_set(), GNUNET_break, GNUNET_OK, GNUNET_SYSERR, handle_set(), and GNUNET_MessageHeader::size.

Referenced by load().

1008 {
1009  uint16_t msize = ntohs (message->size);
1010  const struct GNUNET_STATISTICS_SetMessage *sm;
1011 
1012  sm = (const struct GNUNET_STATISTICS_SetMessage *) message;
1013  if ( (sizeof (struct GNUNET_STATISTICS_SetMessage) > msize) ||
1014  (GNUNET_OK !=
1015  check_set (NULL,
1016  sm)) )
1017  {
1018  GNUNET_break (0);
1019  return GNUNET_SYSERR;
1020  }
1021  handle_set (NULL,
1022  sm);
1023  return GNUNET_OK;
1024 }
Message to set a statistic.
Definition: statistics.h:92
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int check_set(void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
Check format of SET-message.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static void handle_set(void *cls, const struct GNUNET_STATISTICS_SetMessage *msg)
Handle SET-message.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ load()

static void load ( )
static

Load persistent values from disk.

Disk format is exactly the same format that we also use for setting the values over the network.

Definition at line 1032 of file gnunet-service-statistics.c.

References _, buf, fn, GNUNET_BIO_read(), GNUNET_BIO_read_close(), GNUNET_BIO_read_open(), GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_DISK_file_size(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_MST_create(), GNUNET_MST_destroy(), GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OK, GNUNET_YES, and inject_message().

Referenced by run().

1033 {
1034  char *fn;
1035  struct GNUNET_BIO_ReadHandle *rh;
1036  uint64_t fsize;
1037  char *buf;
1038  struct GNUNET_MessageStreamTokenizer *mst;
1039 
1040  if (GNUNET_OK !=
1042  "STATISTICS",
1043  "DATABASE",
1044  &fn))
1045  {
1047  "STATISTICS",
1048  "DATABASE");
1049  return;
1050  }
1051  if ( (GNUNET_OK !=
1053  &fsize,
1054  GNUNET_NO,
1055  GNUNET_YES)) ||
1056  (0 == fsize) )
1057  {
1058  GNUNET_free (fn);
1059  return;
1060  }
1061  buf = GNUNET_malloc (fsize);
1062  rh = GNUNET_BIO_read_open (fn);
1063  if (! rh)
1064  {
1065  GNUNET_free (buf);
1066  GNUNET_free (fn);
1067  return;
1068  }
1069  if (GNUNET_OK !=
1070  GNUNET_BIO_read (rh,
1071  fn,
1072  buf,
1073  fsize))
1074  {
1076  "read",
1077  fn);
1080  NULL));
1081  GNUNET_free (buf);
1082  GNUNET_free (fn);
1083  return;
1084  }
1086  _("Loading %llu bytes of statistics from `%s'\n"),
1087  (unsigned long long) fsize,
1088  fn);
1090  NULL);
1093  buf,
1094  (size_t) fsize,
1095  GNUNET_YES,
1096  GNUNET_NO));
1097  GNUNET_MST_destroy (mst);
1098  GNUNET_free (buf);
1101  NULL));
1102  GNUNET_free (fn);
1103 }
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open file.
Definition: bio.c:119
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open(const char *fn)
Open a file for reading.
Definition: bio.c:94
int GNUNET_BIO_read(struct GNUNET_BIO_ReadHandle *h, const char *what, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: bio.c:145
static int inject_message(void *cls, const struct GNUNET_MessageHeader *message)
We&#39;ve read a struct GNUNET_STATISTICS_SetMessage * from disk.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:413
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
Handle to a message stream tokenizer.
Definition: mst.c:43
static char buf[2048]
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:87
int GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:116
int GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:289
#define GNUNET_log(kind,...)
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_YES
Definition: gnunet_common.h:80
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define GNUNET_malloc(size)
Wrapper around malloc.
Handle for buffered reading.
Definition: bio.c:53
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle service 
)
static

Process statistics requests.

Parameters
clsclosure
cconfiguration to use
servicethe initialized service

Definition at line 1114 of file gnunet-service-statistics.c.

References __attribute__, client_connect_cb(), client_disconnect_cb(), disconnect(), GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT, GNUNET_MESSAGE_TYPE_STATISTICS_GET, GNUNET_MESSAGE_TYPE_STATISTICS_SET, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_notification_context_create(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, load(), shutdown_task(), and watch.

1117 {
1118  cfg = c;
1120  load ();
1122  NULL);
1123 }
static void load()
Load persistent values from disk.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
static void shutdown_task(void *cls)
Task run during shutdown.
static struct GNUNET_NotificationContext * nc
Our notification context.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:125
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

Define "main" method using service macro.

Referenced by run().

Here is the caller graph for this function:

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 211 of file gnunet-service-statistics.c.

◆ sub_head

struct SubsystemEntry* sub_head
static

Head of linked list of subsystems with active statistics.

Definition at line 216 of file gnunet-service-statistics.c.

◆ sub_tail

struct SubsystemEntry* sub_tail
static

Tail of linked list of subsystems with active statistics.

Definition at line 221 of file gnunet-service-statistics.c.

◆ client_count

unsigned int client_count
static

Number of connected clients.

Definition at line 226 of file gnunet-service-statistics.c.

Referenced by client_connect_cb(), client_disconnect_cb(), do_shutdown(), and shutdown_task().

◆ nc

struct GNUNET_NotificationContext* nc
static

Our notification context.

Definition at line 231 of file gnunet-service-statistics.c.

◆ uidgen

uint32_t uidgen
static

Counter used to generate unique values.

Definition at line 236 of file gnunet-service-statistics.c.

Referenced by handle_set(), and handle_watch().

◆ in_shutdown

int in_shutdown
static

Set to GNUNET_YES if we are shutting down as soon as possible.

Definition at line 241 of file gnunet-service-statistics.c.

Referenced by client_disconnect_cb(), and shutdown_task().