Ticket #15: accounting.patch

File accounting.patch, 11.3 KB (added by Emmanuel Bretelle, 14 years ago)

1 diff only

  • configure.ac

    diff --git a/configure.ac b/configure.ac
    index 4626e46..8c76e24 100644
    a b AC_ARG_ENABLE(profiling, 
    199199   [PROFILE="no"]
    200200)
    201201
     202AC_ARG_ENABLE(accounting,
     203   [  --enable-accounting     Enable client accounting support],
     204   [ACCOUNTING="$enableval"],
     205   [ACCOUNTING="no"]
     206)
     207
    202208AC_ARG_ENABLE(strict-options,
    203209   [  --enable-strict-options Enable strict options check between peers (debugging option)],
    204210   [STRICT_OPTIONS="$enableval"],
    if test "$PROFILE" = "yes"; then 
    858864   CFLAGS="$CFLAGS -pg -DENABLE_PROFILING"
    859865fi
    860866
     867dnl enable accounting
     868if test "$ACCOUNTING" = "yes"; then
     869   AC_DEFINE(ENABLE_ACCOUNTING, 1, [Enable client accounting])
     870fi
     871
    861872dnl enable strict options check between peers
    862873if test "$STRICT_OPTIONS" = "yes"; then
    863874   AC_DEFINE(STRICT_OPTIONS_CHECK, 1, [Enable strict options check between peers])
  • init.c

    diff --git a/init.c b/init.c
    index 8ec6ca6..4d4a7c2 100644
    a b do_init_timers (struct context *c, bool deferred) 
    870870        event_timeout_init (&c->c2.occ_mtu_load_test_interval, OCC_MTU_LOAD_INTERVAL_SECONDS, now);
    871871#endif
    872872
     873#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     874      if (c->options.accounting_freq)
     875  event_timeout_init (&c->c2.accounting_interval, c->options.accounting_freq, now);
     876#endif
     877
    873878      /* initialize packet_id persistence timer */
    874879#ifdef USE_CRYPTO
    875880      if (c->options.packet_id_file)
    do_deferred_options (struct context *c, const unsigned int found) 
    14261431    }
    14271432#endif
    14281433
     1434#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     1435  if (found & OPT_P_ACCOUNTING)
     1436    {
     1437      msg (D_PUSH, "OPTIONS IMPORT: accounting interval modified");
     1438      if (c->options.accounting_freq == 0)
     1439        {
     1440          if (event_timeout_defined (&c->c2.accounting_interval))
     1441            event_timeout_clear (&c->c2.accounting_interval);
     1442        }
     1443      else
     1444        {
     1445          if (event_timeout_defined (&c->c2.accounting_interval))
     1446            event_timeout_modify_wakeup( &c->c2.accounting_interval, c->options.accounting_freq);
     1447          else
     1448            event_timeout_init (&c->c2.accounting_interval, c->options.accounting_freq, now);
     1449        }
     1450    }
     1451#endif
    14291452  if (found & OPT_P_SHAPER)
    14301453    {
    14311454      msg (D_PUSH, "OPTIONS IMPORT: traffic shaper enabled");
  • multi.c

    diff --git a/multi.c b/multi.c
    index 7a06bd0..a467580 100644
    a b multi_client_connect_post (struct multi_context *m, 
    13011301                             option_permissions_mask,
    13021302                             option_types_found,
    13031303                             mi->context.c2.es);
    1304 
    13051304      if (!delete_file (dc_file))
    13061305        msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
    13071306             dc_file);
    multi_client_connect_post (struct multi_context *m, 
    13141313       */
    13151314      multi_select_virtual_addr (m, mi);
    13161315      multi_set_virtual_addr_env (m, mi);
     1316
    13171317    }
    13181318}
    13191319
    multi_client_connect_post_plugin (struct multi_context *m, 
    13411341        {
    13421342          if (config.list[i] && config.list[i]->value)
    13431343            options_string_import (&mi->context.options,
    1344                                    config.list[i]->value,
    1345                                    D_IMPORT_ERRORS|M_OPTERR,
    1346                                    option_permissions_mask,
    1347                                    option_types_found,
    1348                                    mi->context.c2.es);
     1344                                     config.list[i]->value,
     1345                                     D_IMPORT_ERRORS|M_OPTERR,
     1346                                     option_permissions_mask,
     1347                                     option_types_found,
     1348                                     mi->context.c2.es);
    13491349        }
    13501350
    13511351      /*
    multi_client_connect_post_plugin (struct multi_context *m, 
    13591359    }
    13601360}
    13611361
    1362 #endif
     1362#ifdef ENABLE_ACCOUNTING
     1363/*
     1364 * Called after stats plug-in is called
     1365 */
     1366static void
     1367multi_accounting_post_plugin (struct multi_context *m,
     1368                                  struct multi_instance *mi,
     1369                                  const struct plugin_return *pr,
     1370                                  unsigned int option_permissions_mask,
     1371                                  unsigned int *option_types_found)
     1372{
     1373  struct plugin_return config;
     1374
     1375  plugin_return_get_column (pr, &config, "config");
     1376
     1377  /* Did script generate a dynamic config file? */
     1378  if (plugin_return_defined (&config))
     1379    {
     1380      int i;
     1381      for (i = 0; i < config.n; ++i)
     1382        {
     1383          if (config.list[i] && config.list[i]->value)
     1384            options_string_import (&mi->context.options,
     1385                                     config.list[i]->value,
     1386                                     D_IMPORT_ERRORS|M_OPTERR,
     1387                                     option_permissions_mask,
     1388                                     option_types_found,
     1389                                     mi->context.c2.es);
     1390        }
     1391    }
     1392}
     1393#endif /* ENABLE_ACCOUNTING */
     1394#endif /* ENABLE_PLUGIN */
    13631395
    13641396#ifdef MANAGEMENT_DEF_AUTH
    13651397
    multi_connection_established (struct multi_context *m, struct multi_instance *mi 
    14511483        | OPT_P_CONFIG
    14521484        | OPT_P_ECHO
    14531485        | OPT_P_COMP
    1454         | OPT_P_SOCKFLAGS;
     1486        | OPT_P_SOCKFLAGS
     1487        | OPT_P_ACCOUNTING;
    14551488
    14561489      int cc_succeeded = true; /* client connect script status */
    14571490      int cc_succeeded_count = 0;
    multi_connection_established (struct multi_context *m, struct multi_instance *mi 
    15211554      /* do --client-connect setenvs */
    15221555      multi_client_connect_setenv (m, mi);
    15231556
     1557
    15241558#ifdef ENABLE_PLUGIN
    15251559      /*
    15261560       * Call client-connect plug-in.
    gremlin_flood_clients (struct multi_context *m) 
    23642398}
    23652399#endif
    23662400
     2401#ifdef ENABLE_ACCOUNTING
     2402/**
     2403 * Process client instances accounting by invoking
     2404 * OPENVPN_PLUGIN_ACCOUNTING
     2405 */
     2406void multi_client_accounting (struct multi_context *m)
     2407{
     2408
     2409  const unsigned int option_permissions_mask = OPT_P_ACCOUNTING;
     2410  unsigned int option_types_found;
     2411  /* for each client context if register to PLUGIN_ACCOUNTING
     2412   * and event should be triggered, send status to plugin
     2413   */
     2414  if (plugin_defined (m->top.plugins, OPENVPN_PLUGIN_ACCOUNTING))
     2415    {
     2416      struct argv argv = argv_new ();
     2417      if (m->hash)
     2418        {
     2419          struct gc_arena gc_top = gc_new ();
     2420          struct hash_iterator hi;
     2421          const struct hash_element *he;
     2422   
     2423          hash_iterator_init (m->hash, &hi, true);
     2424
     2425          while ((he = hash_iterator_next (&hi)))
     2426           {
     2427             struct gc_arena gc = gc_new ();
     2428             struct multi_instance *mi = (struct multi_instance *) he->value;
     2429             if (!mi->halt)
     2430               {
     2431                 struct context *c = &mi->context;
     2432                 struct timeval null;
     2433                 CLEAR (null);
     2434                 if (event_timeout_trigger (&c->c2.accounting_interval, &null, ETT_DEFAULT))
     2435                   {
     2436#ifdef ENABLE_DEBUG
     2437                     msg (M_DEBUG, "DEBUG: ACCOUNTING triggerred after %ds for %s",
     2438                              c->c2.accounting_interval.n,
     2439                              tls_common_name (c->c2.tls_multi, false));
     2440#endif
     2441                     struct plugin_return pr;
     2442                     plugin_return_init (&pr);
     2443
     2444                     option_types_found = 0;
     2445                     setenv_stats (c);
     2446                     if (plugin_call (c->plugins, OPENVPN_PLUGIN_ACCOUNTING, &argv, &pr, c->c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
     2447                       {
     2448                         msg (M_WARN, "WARNING: stats plugin call failed");
     2449                       }
     2450                     else
     2451                       {
     2452                         multi_accounting_post_plugin (m, mi, &pr, option_permissions_mask, &option_types_found);
     2453                         do_deferred_options (c, option_types_found);
     2454                       }
     2455                         plugin_return_free (&pr);
     2456                   }
     2457               }
     2458             gc_free (&gc);
     2459           }
     2460         hash_iterator_free (&hi);
     2461        }
     2462      argv_reset (&argv);
     2463    }
     2464}
     2465#endif
     2466
    23672467/*
    23682468 * Process timers in the top-level context
    23692469 */
    multi_process_per_second_timers_dowork (struct multi_context *m) 
    23802480        multi_print_status (m, m->top.c1.status_output, m->status_file_version);
    23812481    }
    23822482
     2483#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     2484  multi_client_accounting (m);
     2485#endif
     2486
    23832487  /* possibly flush ifconfig-pool file */
    23842488  multi_ifconfig_pool_persist (m, false);
    23852489
  • openvpn-plugin.h

    diff --git a/openvpn-plugin.h b/openvpn-plugin.h
    index 56b0a70..44e62a6 100644
    a b  
    9797#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2     9
    9898#define OPENVPN_PLUGIN_TLS_FINAL             10
    9999#define OPENVPN_PLUGIN_ENABLE_PF             11
    100 #define OPENVPN_PLUGIN_N                     12
     100#define OPENVPN_PLUGIN_ACCOUNTING            12
     101#define OPENVPN_PLUGIN_N                     13
    101102
    102103/*
    103104 * Build a mask out of a set of plug-in types.
  • openvpn.h

    diff --git a/openvpn.h b/openvpn.h
    index 0757eb1..a4711c6 100644
    a b struct context_2 
    305305  int occ_mtu_load_n_tries;
    306306#endif
    307307
     308#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     309  struct event_timeout accounting_interval;
     310#endif
     311
    308312#ifdef USE_CRYPTO
    309313
    310314  /*
    struct context_2 
    447451#ifdef MANAGEMENT_DEF_AUTH
    448452  struct man_def_auth_context mda_context;
    449453#endif
     454
    450455};
    451456
    452457/*
  • options.c

    diff --git a/options.c b/options.c
    index 3a2a6c5..8d33490 100644
    a b static const char usage_message[] = 
    307307  "--status file n : Write operational status to file every n seconds.\n"
    308308  "--status-version [n] : Choose the status file format version number.\n"
    309309  "                  Currently, n can be 1, 2, or 3 (default=1).\n"
     310#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     311  "--accounting-freq s : Send client accounting information every s seconds.\n"
     312#endif
    310313#ifdef ENABLE_OCC
    311314  "--disable-occ   : Disable options consistency check between peers.\n"
    312315#endif
    init_options (struct options *o, const bool init_gc) 
    691694#ifdef ENABLE_OCC
    692695  o->occ = true;
    693696#endif
     697#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     698  o->accounting_freq = 60;
     699#endif
    694700#ifdef ENABLE_MANAGEMENT
    695701  o->management_log_history_cache = 250;
    696702  o->management_echo_buffer_size = 100;
    show_settings (const struct options *o) 
    13821388  show_p2mp_parms (o);
    13831389#endif
    13841390
     1391#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     1392  SHOW_INT (accounting_freq);
     1393#endif
     1394
    13851395#ifdef WIN32
    13861396  SHOW_BOOL (show_net_up);
    13871397  SHOW_INT (route_method);
    add_option (struct options *options, 
    57415751      options->persist_mode = 1;
    57425752    }
    57435753#endif
     5754#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     5755  else if (streq (p[0], "accounting-freq") && p[1])
     5756    {
     5757      int freq;
     5758
     5759      VERIFY_PERMISSION (OPT_P_ACCOUNTING);
     5760      freq = atoi (p[1]);
     5761      if (freq < 0)
     5762  {
     5763    msg (msglevel, "--accounting-freq must be >= 0");
     5764    goto err;
     5765  }
     5766      options->accounting_freq = freq;
     5767    }
     5768#endif
    57445769  else
    57455770    {
    57465771      if (file)
  • options.h

    diff --git a/options.h b/options.h
    index ebff532..19dfd4c 100644
    a b struct options 
    405405
    406406#endif
    407407
     408#if defined(ENABLE_PLUGIN) && defined(ENABLE_ACCOUNTING)
     409  int accounting_freq;
     410#endif
     411
    408412#ifdef USE_CRYPTO
    409413  /* Cipher parms */
    410414  const char *shared_secret_file;
    struct options 
    544548#define OPT_P_SOCKBUF         (1<<25)
    545549#define OPT_P_SOCKFLAGS       (1<<26)
    546550#define OPT_P_CONNECTION      (1<<27)
     551#define OPT_P_ACCOUNTING      (1<<28)
    547552
    548553#define OPT_P_DEFAULT   (~(OPT_P_INSTANCE|OPT_P_PULL_MODE))
    549554
  • plugin.c

    diff --git a/plugin.c b/plugin.c
    index 769de8d..a0ee535 100644
    a b plugin_type_name (const int type) 
    8888      return "PLUGIN_TLS_FINAL";
    8989    case OPENVPN_PLUGIN_ENABLE_PF:
    9090      return "OPENVPN_PLUGIN_ENABLE_PF";
     91    case OPENVPN_PLUGIN_ACCOUNTING:
     92      return "OPENVPN_PLUGIN_ACCOUNTING";
    9193    default:
    9294      return "PLUGIN_???";
    9395    }