aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manage.c18
-rw-r--r--manage.h1
-rw-r--r--multi.c16
-rw-r--r--multi.h2
4 files changed, 37 insertions, 0 deletions
diff --git a/manage.c b/manage.c
index 4248787..7eff627 100644
--- a/manage.c
+++ b/manage.c
@@ -916,6 +916,20 @@ man_client_kill (struct management *man, const char *cid_str)
}
}
+static void
+man_client_n_clients (struct management *man)
+{
+ if (man->persist.callback.n_clients)
+ {
+ const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
+ msg (M_CLIENT, "SUCCESS: nclients=%d", nclients);
+ }
+ else
+ {
+ msg (M_CLIENT, "ERROR: The nclients command is not supported by the current daemon mode");
+ }
+}
+
#ifdef MANAGEMENT_PF
static void
@@ -981,6 +995,10 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
{
msg (M_CLIENT, "SUCCESS: pid=%d", openvpn_getpid ());
}
+ else if (streq (p[0], "nclients"))
+ {
+ man_client_n_clients (man);
+ }
else if (streq (p[0], "signal"))
{
if (man_need (man, p, 1, 0))
diff --git a/manage.h b/manage.h
index e8ae93b..94ec639 100644
--- a/manage.h
+++ b/manage.h
@@ -154,6 +154,7 @@ struct management_callback
int (*kill_by_cn) (void *arg, const char *common_name);
int (*kill_by_addr) (void *arg, const in_addr_t addr, const int port);
void (*delete_event) (void *arg, event_t event);
+ int (*n_clients) (void *arg);
#ifdef MANAGEMENT_DEF_AUTH
bool (*kill_by_cid) (void *arg, const unsigned long cid);
bool (*client_auth) (void *arg,
diff --git a/multi.c b/multi.c
index 733a8b0..6704789 100644
--- a/multi.c
+++ b/multi.c
@@ -503,6 +503,10 @@ multi_close_instance (struct multi_context *m,
dmsg (D_MULTI_DEBUG, "MULTI: multi_close_instance called");
+ /* adjust current client connection count */
+ m->n_clients += mi->n_clients_delta;
+ mi->n_clients_delta = 0;
+
/* prevent dangling pointers */
if (m->pending == mi)
multi_set_pending (m, NULL);
@@ -1688,6 +1692,10 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
/* set flag so we don't get called again */
mi->connection_established_flag = true;
+ /* increment number of current authenticated clients */
+ ++m->n_clients;
+ --mi->n_clients_delta;
+
#ifdef MANAGEMENT_DEF_AUTH
if (management)
management_connection_established (management, &mi->context.c2.mda_context);
@@ -2437,6 +2445,13 @@ management_callback_status (void *arg, const int version, struct status_output *
}
static int
+management_callback_n_clients (void *arg)
+{
+ struct multi_context *m = (struct multi_context *) arg;
+ return m->n_clients;
+}
+
+static int
management_callback_kill_by_cn (void *arg, const char *del_cn)
{
struct multi_context *m = (struct multi_context *) arg;
@@ -2598,6 +2613,7 @@ init_management_callback_multi (struct multi_context *m)
cb.kill_by_cn = management_callback_kill_by_cn;
cb.kill_by_addr = management_callback_kill_by_addr;
cb.delete_event = management_delete_event;
+ cb.n_clients = management_callback_n_clients;
#ifdef MANAGEMENT_DEF_AUTH
cb.kill_by_cid = management_kill_by_cid;
cb.client_auth = management_client_auth;
diff --git a/multi.h b/multi.h
index 7c33d87..55119d6 100644
--- a/multi.h
+++ b/multi.h
@@ -83,6 +83,7 @@ struct multi_instance {
#endif
bool connection_established_flag;
bool did_iroutes;
+ int n_clients_delta; /* added to multi_context.n_clients when instance is closed */
struct context context;
};
@@ -114,6 +115,7 @@ struct multi_context {
int max_clients;
int tcp_queue_limit;
int status_file_version;
+ int n_clients; /* current number of authenticated clients */
#ifdef MANAGEMENT_DEF_AUTH
struct hash *cid_hash;