From: Martin Willi Date: Fri, 15 Mar 2013 09:41:04 +0000 (+0100) Subject: Add connection name specific stroke counters X-Git-Tag: 5.0.3rc1~53^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d022322bed29e0b6d1ca09edb891402d7e2cc73f;p=thirdparty%2Fstrongswan.git Add connection name specific stroke counters --- diff --git a/src/libcharon/plugins/stroke/stroke_counter.c b/src/libcharon/plugins/stroke/stroke_counter.c index 56eda945a1..e64415f5d3 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 +#include 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++) @@ -225,6 +339,17 @@ METHOD(stroke_counter_t, print, void, 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); } @@ -247,6 +372,8 @@ stroke_counter_t *stroke_counter_create() .print = _print, .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 efaae0d6f2..b39fcb8dda 100644 --- a/src/libcharon/plugins/stroke/stroke_counter.h +++ b/src/libcharon/plugins/stroke/stroke_counter.h @@ -87,8 +87,9 @@ 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); /** * Destroy a stroke_counter_t. diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 2771f0146b..ebb3c723d4 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); - } } /** @@ -504,6 +501,17 @@ static void stroke_user_creds(private_stroke_socket_t *this, this->config->set_user_credentials(this->config, msg, out); } +/** + * 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); + + this->counter->print(this->counter, out, msg->counters.name); +} + /** * set the verbosity debug output */ @@ -665,6 +673,8 @@ 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); default: DBG1(DBG_CFG, "received unknown stroke"); break; @@ -855,4 +865,3 @@ stroke_socket_t *stroke_socket_create() return &this->public; } - diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index e289296c14..1be275c285 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -266,7 +266,6 @@ static int list_flags[] = { LIST_OCSP, LIST_ALGS, LIST_PLUGINS, - LIST_COUNTERS, LIST_ALL }; @@ -365,6 +364,16 @@ static int user_credentials(char *name, char *user, char *pass) return send_stroke_msg(&msg); } +static int counters(char *name) +{ + stroke_msg_t msg; + + msg.type = STR_COUNTERS; + msg.length = offsetof(stroke_msg_t, buffer); + msg.counters.name = push_string(&msg, name); + return send_stroke_msg(&msg); +} + static int set_loglevel(char *type, u_int level) { stroke_msg_t msg; @@ -419,7 +428,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"); @@ -445,6 +454,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); } @@ -553,7 +564,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; @@ -594,6 +604,16 @@ int main(int argc, char *argv[]) } res = user_credentials(argv[2], argv[3], argc > 4 ? argv[4] : NULL); break; + case STROKE_COUNTERS: + if (argc > 2) + { + res = counters(argv[2]); + } + else + { + res = counters(NULL); + } + break; default: exit_usage(NULL); } diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h index 0ad87b7056..12abce1d34 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,7 @@ typedef enum { STROKE_LEASES, STROKE_MEMUSAGE, STROKE_USER_CREDS, + STROKE_COUNTERS, } stroke_keyword_t; #define STROKE_LIST_FIRST STROKE_LIST_PUBKEYS @@ -71,4 +71,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 95b2981d90..12c590962c 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,4 @@ exportx509, STROKE_EXPORT_X509 leases, STROKE_LEASES memusage, STROKE_MEMUSAGE user-creds, STROKE_USER_CREDS +listcounters, STROKE_COUNTERS diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index e972a5984e..494acba11d 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; @@ -225,6 +223,8 @@ struct stroke_msg_t { STR_MEMUSAGE, /* set username and password for a connection */ STR_USER_CREDS, + /* print counters */ + STR_COUNTERS, /* more to come */ } type; @@ -354,6 +354,11 @@ struct stroke_msg_t { char *username; char *password; } user_creds; + + /* data for STR_COUNTERS */ + struct { + char *name; + } counters; }; char buffer[STROKE_BUF_LEN]; };