diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ipsec/_ipsec.in | 7 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_counter.c | 157 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_counter.h | 10 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_socket.c | 29 | ||||
-rw-r--r-- | src/stroke/stroke.c | 23 | ||||
-rw-r--r-- | src/stroke/stroke_keywords.h | 4 | ||||
-rw-r--r-- | src/stroke/stroke_keywords.txt | 3 | ||||
-rw-r--r-- | src/stroke/stroke_msg.h | 13 |
8 files changed, 223 insertions, 23 deletions
diff --git a/src/ipsec/_ipsec.in b/src/ipsec/_ipsec.in index 8b6ad660d..6b406f6d9 100644 --- a/src/ipsec/_ipsec.in +++ b/src/ipsec/_ipsec.in @@ -59,7 +59,8 @@ case "$1" in echo " listalgs|listpubkeys|listcerts [--utc]" echo " listcacerts|listaacerts|listocspcerts [--utc]" echo " listacerts|listgroups|listcainfos [--utc]" - echo " listcrls|listocsp|listcards|listplugins|listcounters|listall [--utc]" + echo " listcrls|listocsp|listcards|listplugins|listall [--utc]" + echo " listcounters|resetcounters [name]" echo " leases [<poolname> [<address>]]" echo " rereadsecrets|rereadgroups" echo " rereadcacerts|rereadaacerts|rereadocspcerts" @@ -149,10 +150,10 @@ leases) listalgs|listpubkeys|listplugins|\ listcerts|listcacerts|listaacerts|\ listacerts|listgroups|listocspcerts|\ -listcainfos|listcrls|listocsp|listcounters|listall|\ +listcainfos|listcrls|listocsp|listall|\ rereadsecrets|rereadcacerts|rereadaacerts|\ rereadacerts|rereadocspcerts|rereadcrls|\ -rereadall|purgeocsp) +rereadall|purgeocsp|listcounters|resetcounters) op="$1" rc=7 shift diff --git a/src/libcharon/plugins/stroke/stroke_counter.c b/src/libcharon/plugins/stroke/stroke_counter.c index 56eda945a..ff4746bf4 100644 --- a/src/libcharon/plugins/stroke/stroke_counter.c +++ b/src/libcharon/plugins/stroke/stroke_counter.c @@ -16,6 +16,7 @@ #include "stroke_counter.h" #include <threading/spinlock.h> +#include <collections/hashtable.h> ENUM(stroke_counter_type_names, COUNTER_INIT_IKE_SA_REKEY, COUNTER_OUT_INFORMATIONAL_RSP, @@ -55,16 +56,111 @@ struct private_stroke_counter_t { stroke_counter_t public; /** - * Counter values + * Global counter values */ u_int64_t counter[COUNTER_MAX]; /** + * Counters for specific connection names, char* => entry_t + */ + hashtable_t *conns; + + /** * Lock for counter values */ spinlock_t *lock; }; +/** + * Counters for a specific connection name + */ +typedef struct { + /** connection name */ + char *name; + /** counter values for connection */ + u_int64_t counter[COUNTER_MAX]; +} entry_t; + +/** + * Destroy named entry + */ +static void destroy_entry(entry_t *this) +{ + free(this->name); + free(this); +} + +/** + * Hashtable hash function + */ +static u_int hash(char *name) +{ + return chunk_hash(chunk_from_str(name)); +} + +/** + * Hashtable equals function + */ +static bool equals(char *a, char *b) +{ + return streq(a, b); +} + +/** + * Get the name of an IKE_SA, but return NULL if it is not known yet + */ +static char *get_ike_sa_name(ike_sa_t *ike_sa) +{ + peer_cfg_t *peer_cfg; + + peer_cfg = ike_sa->get_peer_cfg(ike_sa); + if (peer_cfg) + { + return peer_cfg->get_name(peer_cfg); + } + return NULL; +} + +/** + * Increase a counter for a named entry + */ +static void count_named(private_stroke_counter_t *this, + ike_sa_t *ike_sa, stroke_counter_type_t type) +{ + entry_t *entry; + char *name; + + name = get_ike_sa_name(ike_sa); + if (name) + { + entry = this->conns->get(this->conns, name); + if (!entry) + { + INIT(entry, + .name = strdup(name), + ); + this->conns->put(this->conns, entry->name, entry); + } + entry->counter[type]++; + } +} + +/** + * Get a counter value for a specific connection name + */ +static u_int64_t get_named_count(private_stroke_counter_t *this, + char *name, stroke_counter_type_t type) +{ + entry_t *entry; + + entry = this->conns->get(this->conns, name); + if (entry) + { + return entry->counter[type]; + } + return 0; +} + METHOD(listener_t, alert, bool, private_stroke_counter_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args) @@ -86,6 +182,7 @@ METHOD(listener_t, alert, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, ike_sa, type); this->lock->unlock(this->lock); return TRUE; @@ -109,6 +206,7 @@ METHOD(listener_t, ike_rekey, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, old, type); this->lock->unlock(this->lock); return TRUE; @@ -120,6 +218,7 @@ METHOD(listener_t, child_rekey, bool, { this->lock->lock(this->lock); this->counter[COUNTER_CHILD_SA_REKEY]++; + count_named(this, ike_sa, COUNTER_CHILD_SA_REKEY); this->lock->unlock(this->lock); return TRUE; @@ -194,13 +293,14 @@ METHOD(listener_t, message_hook, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, ike_sa, type); this->lock->unlock(this->lock); return TRUE; } METHOD(stroke_counter_t, print, void, - private_stroke_counter_t *this, FILE *out) + private_stroke_counter_t *this, FILE *out, char *name) { u_int64_t counter[COUNTER_MAX]; int i; @@ -209,11 +309,25 @@ METHOD(stroke_counter_t, print, void, this->lock->lock(this->lock); for (i = 0; i < countof(this->counter); i++) { - counter[i] = this->counter[i]; + if (name) + { + counter[i] = get_named_count(this, name, i); + } + else + { + counter[i] = this->counter[i]; + } } this->lock->unlock(this->lock); - fprintf(out, "\nList of IKE counters:\n\n"); + if (name) + { + fprintf(out, "\nList of IKE counters for '%s':\n\n", name); + } + else + { + fprintf(out, "\nList of IKE counters:\n\n"); + } /* but do blocking write without the lock. */ for (i = 0; i < countof(this->counter); i++) @@ -222,9 +336,41 @@ METHOD(stroke_counter_t, print, void, } } +METHOD(stroke_counter_t, reset, void, + private_stroke_counter_t *this, char *name) +{ + this->lock->lock(this->lock); + if (name) + { + entry_t *entry; + + entry = this->conns->remove(this->conns, name); + if (entry) + { + destroy_entry(entry); + } + } + else + { + memset(&this->counter, 0, sizeof(this->counter)); + } + this->lock->unlock(this->lock); +} + METHOD(stroke_counter_t, destroy, void, private_stroke_counter_t *this) { + enumerator_t *enumerator; + char *name; + entry_t *entry; + + enumerator = this->conns->create_enumerator(this->conns); + while (enumerator->enumerate(enumerator, &name, &entry)) + { + destroy_entry(entry); + } + enumerator->destroy(enumerator); + this->conns->destroy(this->conns); this->lock->destroy(this->lock); free(this); } @@ -245,8 +391,11 @@ stroke_counter_t *stroke_counter_create() .message = _message_hook, }, .print = _print, + .reset = _reset, .destroy = _destroy, }, + .conns = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 4), .lock = spinlock_create(), ); diff --git a/src/libcharon/plugins/stroke/stroke_counter.h b/src/libcharon/plugins/stroke/stroke_counter.h index efaae0d6f..fecf39f56 100644 --- a/src/libcharon/plugins/stroke/stroke_counter.h +++ b/src/libcharon/plugins/stroke/stroke_counter.h @@ -87,8 +87,16 @@ struct stroke_counter_t { * Print counter values to an output stream. * * @param out output stream to write to + * @param name connection name to get counters for, NULL for global */ - void (*print)(stroke_counter_t *this, FILE *out); + void (*print)(stroke_counter_t *this, FILE *out, char *name); + + /** + * Reset global or connection specific counters. + * + * @param name name of connection counters to reset, NULL for global + */ + void (*reset)(stroke_counter_t *this, char *name); /** * Destroy a stroke_counter_t. diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index e31616cf8..aa5c73b8b 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -388,17 +388,14 @@ static void stroke_status(private_stroke_socket_t *this, /** * list various information */ -static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out) +static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, + FILE *out) { if (msg->list.flags & LIST_CAINFOS) { this->ca->list(this->ca, msg, out); } this->list->list(this->list, msg, out); - if (msg->list.flags & LIST_COUNTERS) - { - this->counter->print(this->counter, out); - } } /** @@ -505,6 +502,24 @@ static void stroke_user_creds(private_stroke_socket_t *this, } /** + * Print stroke counter values + */ +static void stroke_counters(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->counters.name); + + if (msg->counters.reset) + { + this->counter->reset(this->counter, msg->counters.name); + } + else + { + this->counter->print(this->counter, out, msg->counters.name); + } +} + +/** * set the verbosity debug output */ static void stroke_loglevel(private_stroke_socket_t *this, @@ -672,6 +687,9 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_USER_CREDS: stroke_user_creds(this, msg, out); break; + case STR_COUNTERS: + stroke_counters(this, msg, out); + break; default: DBG1(DBG_CFG, "received unknown stroke"); break; @@ -862,4 +880,3 @@ stroke_socket_t *stroke_socket_create() return &this->public; } - diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index c2a505141..3273aedf2 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -268,7 +268,6 @@ static int list_flags[] = { LIST_OCSP, LIST_ALGS, LIST_PLUGINS, - LIST_COUNTERS, LIST_ALL }; @@ -367,6 +366,18 @@ static int user_credentials(char *name, char *user, char *pass) return send_stroke_msg(&msg); } +static int counters(int reset, char *name) +{ + stroke_msg_t msg; + + msg.type = STR_COUNTERS; + msg.length = offsetof(stroke_msg_t, buffer); + msg.counters.name = push_string(&msg, name); + msg.counters.reset = reset; + + return send_stroke_msg(&msg); +} + static int set_loglevel(char *type, u_int level) { stroke_msg_t msg; @@ -421,7 +432,7 @@ static void exit_usage(char *error) printf(" Show list of authority and attribute certificates:\n"); printf(" stroke listcacerts|listocspcerts|listaacerts|listacerts\n"); printf(" Show list of end entity certificates, ca info records and crls:\n"); - printf(" stroke listcerts|listcainfos|listcrls|listcounters|listall\n"); + printf(" stroke listcerts|listcainfos|listcrls|listall\n"); printf(" Show list of supported algorithms:\n"); printf(" stroke listalgs\n"); printf(" Reload authority and attribute certificates:\n"); @@ -447,6 +458,8 @@ static void exit_usage(char *error) printf(" where: NAME is a connection name added with \"stroke add\"\n"); printf(" USERNAME is the username\n"); printf(" PASSWORD is the optional password, you'll be asked to enter it if not given\n"); + printf(" Show IKE counters:\n"); + printf(" stroke listcounters [connection-name]\n"); exit_error(error); } @@ -555,7 +568,6 @@ int main(int argc, char *argv[]) case STROKE_LIST_OCSP: case STROKE_LIST_ALGS: case STROKE_LIST_PLUGINS: - case STROKE_LIST_COUNTERS: case STROKE_LIST_ALL: res = list(token->kw, argc > 2 && strcmp(argv[2], "--utc") == 0); break; @@ -596,6 +608,11 @@ int main(int argc, char *argv[]) } res = user_credentials(argv[2], argv[3], argc > 4 ? argv[4] : NULL); break; + case STROKE_COUNTERS: + case STROKE_COUNTERS_RESET: + res = counters(token->kw == STROKE_COUNTERS_RESET, + argc > 2 ? argv[2] : NULL); + break; default: exit_usage(NULL); } diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h index 0ad87b705..f5979a0e5 100644 --- a/src/stroke/stroke_keywords.h +++ b/src/stroke/stroke_keywords.h @@ -42,7 +42,6 @@ typedef enum { STROKE_LIST_OCSP, STROKE_LIST_ALGS, STROKE_LIST_PLUGINS, - STROKE_LIST_COUNTERS, STROKE_LIST_ALL, STROKE_REREAD_SECRETS, STROKE_REREAD_CACERTS, @@ -59,6 +58,8 @@ typedef enum { STROKE_LEASES, STROKE_MEMUSAGE, STROKE_USER_CREDS, + STROKE_COUNTERS, + STROKE_COUNTERS_RESET, } stroke_keyword_t; #define STROKE_LIST_FIRST STROKE_LIST_PUBKEYS @@ -71,4 +72,3 @@ typedef struct stroke_token stroke_token_t; extern const stroke_token_t* in_word_set(register const char *str, register unsigned int len); #endif /* _STROKE_KEYWORDS_H_ */ - diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt index 95b2981d9..5d2ebd9e2 100644 --- a/src/stroke/stroke_keywords.txt +++ b/src/stroke/stroke_keywords.txt @@ -49,7 +49,6 @@ listcrls, STROKE_LIST_CRLS listocsp, STROKE_LIST_OCSP listalgs, STROKE_LIST_ALGS listplugins, STROKE_LIST_PLUGINS -listcounters, STROKE_LIST_COUNTERS listall, STROKE_LIST_ALL rereadsecrets, STROKE_REREAD_SECRETS rereadcacerts, STROKE_REREAD_CACERTS @@ -66,3 +65,5 @@ exportx509, STROKE_EXPORT_X509 leases, STROKE_LEASES memusage, STROKE_MEMUSAGE user-creds, STROKE_USER_CREDS +listcounters, STROKE_COUNTERS +resetcounters, STROKE_COUNTERS_RESET diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index a9c6f2369..5cee916cd 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -67,10 +67,8 @@ enum list_flag_t { LIST_ALGS = 0x0400, /** list plugin information */ LIST_PLUGINS = 0x0800, - /** list IKE counters */ - LIST_COUNTERS = 0x1000, /** all list options */ - LIST_ALL = 0x1FFF, + LIST_ALL = 0x0FFF, }; typedef enum reread_flag_t reread_flag_t; @@ -226,6 +224,8 @@ struct stroke_msg_t { STR_MEMUSAGE, /* set username and password for a connection */ STR_USER_CREDS, + /* print/reset counters */ + STR_COUNTERS, /* more to come */ } type; @@ -356,6 +356,13 @@ struct stroke_msg_t { char *username; char *password; } user_creds; + + /* data for STR_COUNTERS */ + struct { + /* reset or print counters? */ + int reset; + char *name; + } counters; }; char buffer[STROKE_BUF_LEN]; }; |