diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-03-01 10:48:08 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-03-01 10:48:08 +0000 |
commit | a6f902baed7abb17a1a9c014e01bb100077f8198 (patch) | |
tree | 82114e22e251e9260d9a712f1232e52e1ef494e3 /src/charon/plugins/stroke | |
parent | 1450c9df799b0870477f6e63357f4bcb63537f4f (diff) | |
download | vyos-strongswan-a6f902baed7abb17a1a9c014e01bb100077f8198.tar.gz vyos-strongswan-a6f902baed7abb17a1a9c014e01bb100077f8198.zip |
- Updated to new upstream revision.
Diffstat (limited to 'src/charon/plugins/stroke')
-rw-r--r-- | src/charon/plugins/stroke/Makefile.in | 18 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_attribute.c | 319 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_attribute.h | 29 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_config.c | 6 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_cred.c | 90 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_list.c | 127 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_list.h | 20 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_socket.c | 17 |
8 files changed, 531 insertions, 95 deletions
diff --git a/src/charon/plugins/stroke/Makefile.in b/src/charon/plugins/stroke/Makefile.in index 1ff213165..645ae2a48 100644 --- a/src/charon/plugins/stroke/Makefile.in +++ b/src/charon/plugins/stroke/Makefile.in @@ -87,22 +87,17 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ -ECHO = @ECHO@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ +FGREP = @FGREP@ GPERF = @GPERF@ GREP = @GREP@ INSTALL = @INSTALL@ @@ -112,6 +107,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@ IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@ +LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ @@ -120,12 +116,16 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LINUX_HEADERS = @LINUX_HEADERS@ +LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NM = @NM@ NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -148,8 +148,7 @@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -188,6 +187,7 @@ libstrongswan_plugins = @libstrongswan_plugins@ linuxdir = @linuxdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c index 71b56bc8a..7591a1e27 100644 --- a/src/charon/plugins/stroke/stroke_attribute.c +++ b/src/charon/plugins/stroke/stroke_attribute.c @@ -19,9 +19,10 @@ #include <daemon.h> #include <utils/linked_list.h> +#include <utils/hashtable.h> #include <utils/mutex.h> -#define POOL_LIMIT 16 +#define POOL_LIMIT (sizeof(uintptr_t)*8) typedef struct private_stroke_attribute_t private_stroke_attribute_t; @@ -51,20 +52,53 @@ typedef struct { char *name; /** base address of the pool */ host_t *base; - /** number of entries in the pool */ - int count; - /** array of in-use flags, TODO: use bit fields */ - u_int8_t *in_use; + /** size of the pool */ + int size; + /** next unused address */ + int unused; + /** hashtable [identity => offset], for online leases */ + hashtable_t *online; + /** hashtable [identity => offset], for offline leases */ + hashtable_t *offline; + /** hashtable [identity => identity], handles identity references */ + hashtable_t *ids; } pool_t; /** + * hashtable hash function for identities + */ +static u_int id_hash(identification_t *id) +{ + return chunk_hash(id->get_encoding(id)); +} + +/** + * hashtable equals function for identities + */ +static bool id_equals(identification_t *a, identification_t *b) +{ + return a->equals(a, b); +} + +/** * destroy a pool_t */ static void pool_destroy(pool_t *this) { + enumerator_t *enumerator; + identification_t *id; + + enumerator = this->ids->create_enumerator(this->ids); + while (enumerator->enumerate(enumerator, &id, NULL)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + this->ids->destroy(this->ids); + this->online->destroy(this->online); + this->offline->destroy(this->offline); DESTROY_IF(this->base); free(this->name); - free(this->in_use); free(this); } @@ -98,7 +132,8 @@ host_t* offset2host(pool_t *pool, int offset) host_t *host; u_int32_t *pos; - if (offset > pool->count) + offset--; + if (offset > pool->size) { return NULL; } @@ -144,11 +179,11 @@ int host2offset(pool_t *pool, host_t *addr) } hosti = ntohl(*(u_int32_t*)(host.ptr)); basei = ntohl(*(u_int32_t*)(base.ptr)); - if (hosti > basei + pool->count) + if (hosti > basei + pool->size) { return -1; } - return hosti - basei; + return hosti - basei + 1; } /** @@ -159,67 +194,120 @@ static host_t* acquire_address(private_stroke_attribute_t *this, auth_info_t *auth, host_t *requested) { pool_t *pool; - host_t *host = NULL; - int i; + uintptr_t offset = 0; + enumerator_t *enumerator; + identification_t *old_id; this->mutex->lock(this->mutex); pool = find_pool(this, name); - if (pool) + while (pool) { - if (requested && !requested->is_anyaddr(requested)) + /* handle %config case by mirroring requested address */ + if (pool->size == 0) { - if (pool->count == 0) - { /* %config, give any */ - host = requested->clone(requested); - } - else + this->mutex->unlock(this->mutex); + return requested->clone(requested); + } + + if (requested->get_family(requested) != + pool->base->get_family(pool->base)) + { + DBG1(DBG_CFG, "IP pool address family mismatch"); + break; + } + + /* check for a valid offline lease, refresh */ + offset = (uintptr_t)pool->offline->remove(pool->offline, id); + if (offset) + { + id = pool->ids->get(pool->ids, id); + if (id) { - i = host2offset(pool, requested); - if (i >= 0 && !pool->in_use[i]) - { - pool->in_use[i] = TRUE; - host = requested->clone(requested); - } + DBG1(DBG_CFG, "reassigning offline lease to %D", id); + pool->online->put(pool->online, id, (void*)offset); + break; } } - if (!host) + + /* check for a valid online lease, reassign */ + offset = (uintptr_t)pool->online->get(pool->online, id); + if (offset && offset == host2offset(pool, requested)) + { + DBG1(DBG_CFG, "reassigning online lease to %D", id); + break; + } + + if (pool->unused < pool->size) + { + /* assigning offset, starting by 1. Handling 0 in hashtable + * is difficult. */ + offset = ++pool->unused; + id = id->clone(id); + pool->ids->put(pool->ids, id, id); + pool->online->put(pool->online, id, (void*)offset); + DBG1(DBG_CFG, "assigning new lease to %D", id); + break; + } + /* no more addresses, replace the first found offline lease */ + enumerator = pool->offline->create_enumerator(pool->offline); + if (enumerator->enumerate(enumerator, &old_id, &offset)) { - for (i = 0; i < pool->count; i++) + offset = (uintptr_t)pool->offline->remove(pool->offline, old_id); + if (offset) { - if (!pool->in_use[i]) + /* destroy reference to old ID */ + old_id = pool->ids->remove(pool->ids, old_id); + DBG1(DBG_CFG, "reassigning existing offline lease of %D to %D", + old_id, id); + if (old_id) { - pool->in_use[i] = TRUE; - host = offset2host(pool, i); - break; + old_id->destroy(old_id); } + id = id->clone(id); + pool->ids->put(pool->ids, id, id); + pool->online->put(pool->online, id, (void*)offset); + enumerator->destroy(enumerator); + break; } } + enumerator->destroy(enumerator); + + DBG1(DBG_CFG, "pool '%s' is full, unable to assign address", name); + break; } this->mutex->unlock(this->mutex); - return host; + if (offset) + { + return offset2host(pool, offset); + } + return NULL; } /** * Implementation of attribute_provider_t.release_address */ static bool release_address(private_stroke_attribute_t *this, - char *name, host_t *address) + char *name, host_t *address, identification_t *id) { pool_t *pool; bool found = FALSE; - int i; + uintptr_t offset; this->mutex->lock(this->mutex); pool = find_pool(this, name); if (pool) { - if (pool->count != 0) + if (pool->size != 0) { - i = host2offset(pool, address); - if (i >= 0 && pool->in_use[i]) + offset = (uintptr_t)pool->online->remove(pool->online, id); + if (offset) { - pool->in_use[i] = FALSE; - found = TRUE; + id = pool->ids->get(pool->ids, id); + if (id) + { + DBG1(DBG_CFG, "lease %H of %D went offline", address, id); + pool->offline->put(pool->offline, id, (void*)offset); + } } } } @@ -236,6 +324,19 @@ static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg) { pool_t *pool; + pool = malloc_thing(pool_t); + pool->base = NULL; + pool->size = 0; + pool->unused = 0; + pool->name = strdup(msg->add_conn.name); + pool->online = hashtable_create((hashtable_hash_t)id_hash, + (hashtable_equals_t)id_equals, 16); + pool->offline = hashtable_create((hashtable_hash_t)id_hash, + (hashtable_equals_t)id_equals, 16); + pool->ids = hashtable_create((hashtable_hash_t)id_hash, + (hashtable_equals_t)id_equals, 16); + + /* if %config, add an empty pool, otherwise */ if (msg->add_conn.other.sourceip) { u_int32_t bits; @@ -245,15 +346,13 @@ static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg) msg->add_conn.name, msg->add_conn.other.sourceip, msg->add_conn.other.sourceip_size); - pool = malloc_thing(pool_t); pool->base = host_create_from_string(msg->add_conn.other.sourceip, 0); if (!pool->base) { - free(pool); + pool_destroy(pool); DBG1(DBG_CFG, "virtual IP address invalid, discarded"); return; } - pool->name = strdup(msg->add_conn.name); family = pool->base->get_family(pool->base); bits = (family == AF_INET ? 32 : 128) - msg->add_conn.other.sourceip_size; if (bits > POOL_LIMIT) @@ -263,23 +362,14 @@ static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg) msg->add_conn.other.sourceip, (family == AF_INET ? 32 : 128) - bits); } - pool->count = 1 << (bits); - pool->in_use = calloc(pool->count, sizeof(u_int8_t)); - - if (pool->count > 2) + pool->size = 1 << (bits); + + if (pool->size > 2) { /* do not use first and last addresses of a block */ - pool->in_use[0] = TRUE; - pool->in_use[pool->count-1] = TRUE; + pool->unused++; + pool->size--; } } - else - { /* %config, add an empty pool */ - pool = malloc_thing(pool_t); - pool->name = strdup(msg->add_conn.name); - pool->base = NULL; - pool->count = 0; - pool->in_use = NULL; - } this->mutex->lock(this->mutex); this->pools->insert_last(this->pools, pool); this->mutex->unlock(this->mutex); @@ -310,6 +400,119 @@ static void del_pool(private_stroke_attribute_t *this, stroke_msg_t *msg) } /** + * Pool enumerator filter function, converts pool_t to name, size, ... + */ +static bool pool_filter(void *mutex, pool_t **poolp, char **name, + void *d1, u_int *size, void *d2, u_int *online, + void *d3, u_int *offline) +{ + pool_t *pool = *poolp; + + *name = pool->name; + *size = pool->size; + *online = pool->online->get_count(pool->online); + *offline = pool->offline->get_count(pool->offline); + return TRUE; +} + +/** + * Implementation of stroke_attribute_t.create_pool_enumerator + */ +static enumerator_t* create_pool_enumerator(private_stroke_attribute_t *this) +{ + this->mutex->lock(this->mutex); + return enumerator_create_filter(this->pools->create_enumerator(this->pools), + (void*)pool_filter, + this->mutex, (void*)this->mutex->unlock); +} + +/** + * lease enumerator + */ +typedef struct { + /** implemented enumerator interface */ + enumerator_t public; + /** inner hash-table enumerator */ + enumerator_t *inner; + /** enumerated pool */ + pool_t *pool; + /** mutex to unlock on destruction */ + mutex_t *mutex; + /** currently enumerated lease address */ + host_t *current; +} lease_enumerator_t; + +/** + * Implementation of lease_enumerator_t.enumerate + */ +static bool lease_enumerate(lease_enumerator_t *this, identification_t **id_out, + host_t **addr_out, bool *online) +{ + identification_t *id; + uintptr_t offset; + + DESTROY_IF(this->current); + this->current = NULL; + + if (this->inner->enumerate(this->inner, &id, NULL)) + { + offset = (uintptr_t)this->pool->online->get(this->pool->online, id); + if (offset) + { + *id_out = id; + *addr_out = this->current = offset2host(this->pool, offset); + *online = TRUE; + return TRUE; + } + offset = (uintptr_t)this->pool->offline->get(this->pool->offline, id); + if (offset) + { + *id_out = id; + *addr_out = this->current = offset2host(this->pool, offset); + *online = FALSE; + return TRUE; + } + } + return FALSE; +} + +/** + * Implementation of lease_enumerator_t.destroy + */ +static void lease_enumerator_destroy(lease_enumerator_t *this) +{ + DESTROY_IF(this->current); + this->inner->destroy(this->inner); + this->mutex->unlock(this->mutex); + free(this); +} + +/** + * Implementation of stroke_attribute_t.create_lease_enumerator + */ +static enumerator_t* create_lease_enumerator(private_stroke_attribute_t *this, + char *pool) +{ + lease_enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = malloc_thing(lease_enumerator_t); + enumerator->pool = find_pool(this, pool); + if (!enumerator->pool) + { + this->mutex->unlock(this->mutex); + free(enumerator); + return NULL; + } + enumerator->public.enumerate = (void*)lease_enumerate; + enumerator->public.destroy = (void*)lease_enumerator_destroy; + enumerator->inner = enumerator->pool->ids->create_enumerator(enumerator->pool->ids); + enumerator->mutex = this->mutex; + enumerator->current = NULL; + return &enumerator->public; +} + +/** * Implementation of stroke_attribute_t.destroy */ static void destroy(private_stroke_attribute_t *this) @@ -327,13 +530,15 @@ stroke_attribute_t *stroke_attribute_create() private_stroke_attribute_t *this = malloc_thing(private_stroke_attribute_t); this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address; - this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *))release_address; + this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address; this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool; this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool; + this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator; + this->public.create_lease_enumerator = (enumerator_t*(*)(stroke_attribute_t*, char *pool))create_lease_enumerator; this->public.destroy = (void(*)(stroke_attribute_t*))destroy; this->pools = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_RECURSIVE); return &this->public; } diff --git a/src/charon/plugins/stroke/stroke_attribute.h b/src/charon/plugins/stroke/stroke_attribute.h index f871d5a13..5060dc987 100644 --- a/src/charon/plugins/stroke/stroke_attribute.h +++ b/src/charon/plugins/stroke/stroke_attribute.h @@ -32,7 +32,7 @@ typedef struct stroke_attribute_t stroke_attribute_t; * Stroke IKEv2 cfg attribute provider */ struct stroke_attribute_t { - + /** * Implements attribute provider interface */ @@ -54,9 +54,30 @@ struct stroke_attribute_t { void (*del_pool)(stroke_attribute_t *this, stroke_msg_t *msg); /** - * Destroy a stroke_attribute instance. - */ - void (*destroy)(stroke_attribute_t *this); + * Create an enumerator over installed pools. + * + * Enumerator enumerates over + * char *pool, u_int size, u_int offline, u_int online. + * + * @return enumerator + */ + enumerator_t* (*create_pool_enumerator)(stroke_attribute_t *this); + + /** + * Create an enumerator over the leases of a pool. + * + * Enumerator enumerates over + * identification_t *id, host_t *address, bool online + * + * @param pool name of the pool to enumerate + * @return enumerator, NULL if pool not found + */ + enumerator_t* (*create_lease_enumerator)(stroke_attribute_t *this, + char *pool); + /** + * Destroy a stroke_attribute instance. + */ + void (*destroy)(stroke_attribute_t *this); }; /** diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c index cb91ecb72..59c58ca0d 100644 --- a/src/charon/plugins/stroke/stroke_config.c +++ b/src/charon/plugins/stroke/stroke_config.c @@ -374,6 +374,12 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, return NULL; } + if (msg->add_conn.ikeme.mediation) + { + /* force unique connections for mediation connections */ + msg->add_conn.unique = 1; + } + if (msg->add_conn.ikeme.mediated_by) { mediated_by = charon->backends->get_peer_cfg_by_name(charon->backends, diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c index 23a6f99b0..07e0ca768 100644 --- a/src/charon/plugins/stroke/stroke_cred.c +++ b/src/charon/plugins/stroke/stroke_cred.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -720,13 +721,23 @@ static void load_secrets(private_stroke_cred_t *this) { continue; } - if (!extract_last_token(&ids, ':', &line)) + if (line.len > 2 && strneq(": ", line.ptr, 2)) { - DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr); + /* no ids, skip the ':' */ + ids = chunk_empty; + line.ptr++; + line.len--; + } + else if (extract_token_str(&ids, " : ", &line)) + { + /* NULL terminate the extracted id string */ + *(ids.ptr + ids.len) = '\0'; + } + else + { + DBG1(DBG_CFG, "line %d: missing ' : ' separator", line_nr); goto error; } - /* NULL terminate the ids string by replacing the : separator */ - *(ids.ptr + ids.len) = '\0'; if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line)) { @@ -791,10 +802,75 @@ static void load_secrets(private_stroke_cred_t *this) } chunk_clear(&secret); } + else if (match("PIN", &token)) + { + chunk_t sc = chunk_empty; + char smartcard[32], keyid[22], pin[32]; + private_key_t *key; + u_int slot; + + err_t ugh = extract_value(&sc, &line); + + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); + goto error; + } + if (sc.len == 0) + { + DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr); + goto error; + } + snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr); + smartcard[sizeof(smartcard) - 1] = '\0'; + + /* parse slot and key id. only two formats are supported. + * first try %smartcard<slot>:<keyid> */ + if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2) + { + snprintf(smartcard, sizeof(smartcard), "%u:%s", slot, keyid); + } + /* then try %smartcard:<keyid> */ + else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1) + { + snprintf(smartcard, sizeof(smartcard), "%s", keyid); + } + else + { + DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not" + " supported or invalid", line_nr); + goto error; + } + + if (!eat_whitespace(&line)) + { + DBG1(DBG_CFG, "line %d: expected PIN", line_nr); + goto error; + } + ugh = extract_secret(&chunk, &line); + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh); + goto error; + } + snprintf(pin, sizeof(pin), "%.*s", chunk.len, chunk.ptr); + pin[sizeof(pin) - 1] = '\0'; + + /* we assume an RSA key */ + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_SMARTCARD_KEYID, smartcard, + BUILD_SMARTCARD_PIN, pin, BUILD_END); + + if (key) + { + DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr); + this->private->insert_last(this->private, key); + } + memset(pin, 0, sizeof(pin)); + } else if ((match("PSK", &token) && (type = SHARED_IKE)) || (match("EAP", &token) && (type = SHARED_EAP)) || - (match("XAUTH", &token) && (type = SHARED_EAP)) || - (match("PIN", &token) && (type = SHARED_PIN))) + (match("XAUTH", &token) && (type = SHARED_EAP))) { stroke_shared_key_t *shared_key; chunk_t secret = chunk_empty; @@ -862,7 +938,7 @@ static void load_secrets(private_stroke_cred_t *this) else { DBG1(DBG_CFG, "line %d: token must be either " - "RSA, EC, PSK, EAP, or PIN", line_nr); + "RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr); goto error; } } diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 7d0ad4557..8042875c9 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -47,6 +47,11 @@ struct private_stroke_list_t { * timestamp of daemon start */ time_t uptime; + + /** + * strokes attribute provider + */ + stroke_attribute_t *attribute; }; /** @@ -72,10 +77,21 @@ auth_class_t get_auth_class(peer_cfg_t *config) static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) { ike_sa_id_t *id = ike_sa->get_id(ike_sa); - - fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n", + time_t now = time(NULL); + + fprintf(out, "%12s[%d]: %N", ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), - ike_sa_state_names, ike_sa->get_state(ike_sa), + ike_sa_state_names, ike_sa->get_state(ike_sa)); + + if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) + { + time_t established; + + established = ike_sa->get_statistic(ike_sa, STAT_ESTABLISHED); + fprintf(out, " %#V ago", &now, &established); + } + + fprintf(out, ", %H[%D]...%H[%D]\n", ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa), ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa)); @@ -93,22 +109,20 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) { - u_int32_t rekey, reauth, now; + time_t rekey, reauth; - now = time(NULL); rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY); reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH); if (rekey) { - rekey -= now; - fprintf(out, ", rekeying in %V", &rekey); + fprintf(out, ", rekeying in %#V", &rekey, &now); } if (reauth) { - reauth -= now; - fprintf(out, ", %N reauthentication in %V", auth_class_names, - get_auth_class(ike_sa->get_peer_cfg(ike_sa)), &reauth); + fprintf(out, ", %N reauthentication in %#V", auth_class_names, + get_auth_class(ike_sa->get_peer_cfg(ike_sa)), + &reauth, &now); } if (!rekey && !reauth) { @@ -248,11 +262,13 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo if (all) { peer_cfg_t *peer_cfg; - char *plugin; + char *plugin, *pool; host_t *host; u_int32_t dpd; time_t uptime = time(NULL) - this->uptime; - + bool first = TRUE; + u_int size, online, offline; + fprintf(out, "Performance:\n"); fprintf(out, " uptime: %V, since %#T\n", &uptime, &this->uptime, FALSE); fprintf(out, " worker threads: %d idle of %d,", @@ -271,6 +287,18 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo enumerator->destroy(enumerator); fprintf(out, "\n"); + enumerator = this->attribute->create_pool_enumerator(this->attribute); + while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline)) + { + if (first) + { + first = FALSE; + fprintf(out, "Virtual IP pools (size/online/offline):\n"); + } + fprintf(out, " %s: %lu/%lu/%lu\n", pool, size, online, offline); + } + enumerator->destroy(enumerator); + enumerator = charon->kernel_interface->create_address_enumerator( charon->kernel_interface, FALSE, FALSE); fprintf(out, "Listening IP addresses:\n"); @@ -969,6 +997,77 @@ static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) } /** + * Print leases of a single pool + */ +static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool, + host_t *address, u_int size, u_int online, u_int offline) +{ + enumerator_t *enumerator; + identification_t *id; + host_t *lease; + bool on; + int found = 0; + + fprintf(out, "Leases in pool '%s', usage: %lu/%lu, %lu online\n", + pool, online + offline, size, online); + enumerator = this->attribute->create_lease_enumerator(this->attribute, pool); + while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on)) + { + if (!address || address->ip_equals(address, lease)) + { + fprintf(out, " %15H %s '%D'\n", + lease, on ? "online" : "offline", id); + found++; + } + } + enumerator->destroy(enumerator); + if (!found) + { + fprintf(out, " no matching leases found\n"); + } +} + +/** + * Implementation of stroke_list_t.leases + */ +static void leases(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) +{ + enumerator_t *enumerator; + u_int size, offline, online; + host_t *address = NULL; + char *pool; + int found = 0; + + if (msg->leases.address) + { + address = host_create_from_string(msg->leases.address, 0); + } + + enumerator = this->attribute->create_pool_enumerator(this->attribute); + while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline)) + { + if (!msg->leases.pool || streq(msg->leases.pool, pool)) + { + pool_leases(this, out, pool, address, size, online, offline); + found++; + } + } + enumerator->destroy(enumerator); + if (!found) + { + if (msg->leases.pool) + { + fprintf(out, "pool '%s' not found\n", msg->leases.pool); + } + else + { + fprintf(out, "no pools found\n"); + } + } + DESTROY_IF(address); +} + +/** * Implementation of stroke_list_t.destroy */ static void destroy(private_stroke_list_t *this) @@ -979,15 +1078,17 @@ static void destroy(private_stroke_list_t *this) /* * see header file */ -stroke_list_t *stroke_list_create() +stroke_list_t *stroke_list_create(stroke_attribute_t *attribute) { private_stroke_list_t *this = malloc_thing(private_stroke_list_t); this->public.list = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))list; this->public.status = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out,bool))status; + this->public.leases = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))leases; this->public.destroy = (void(*)(stroke_list_t*))destroy; this->uptime = time(NULL); + this->attribute = attribute; return &this->public; } diff --git a/src/charon/plugins/stroke/stroke_list.h b/src/charon/plugins/stroke/stroke_list.h index dabdbff39..1f7f19d62 100644 --- a/src/charon/plugins/stroke/stroke_list.h +++ b/src/charon/plugins/stroke/stroke_list.h @@ -23,6 +23,8 @@ #ifndef STROKE_LIST_H_ #define STROKE_LIST_H_ +#include "stroke_attribute.h" + #include <stroke_msg.h> #include <library.h> @@ -51,14 +53,24 @@ struct stroke_list_t { void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all); /** - * Destroy a stroke_list instance. - */ - void (*destroy)(stroke_list_t *this); + * Log pool leases to stroke console. + * + * @param msg stroke message + * @param out stroke console stream + */ + void (*leases)(stroke_list_t *this, stroke_msg_t *msg, FILE *out); + + /** + * Destroy a stroke_list instance. + */ + void (*destroy)(stroke_list_t *this); }; /** * Create a stroke_list instance. + * + * @param attribute strokes attribute provider */ -stroke_list_t *stroke_list_create(); +stroke_list_t *stroke_list_create(stroke_attribute_t *attribute); #endif /* STROKE_LIST_H_ @}*/ diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c index 8c4ab7804..53edde031 100644 --- a/src/charon/plugins/stroke/stroke_socket.c +++ b/src/charon/plugins/stroke/stroke_socket.c @@ -337,6 +337,18 @@ static void stroke_purge(private_stroke_socket_t *this, CERT_X509_OCSP_RESPONSE); } +/** + * list pool leases + */ +static void stroke_leases(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->leases.pool); + pop_string(msg, &msg->leases.address); + + this->list->leases(this->list, msg, out); +} + debug_t get_group_from_name(char *type) { if (strcasecmp(type, "any") == 0) return DBG_ANY; @@ -498,6 +510,9 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_PURGE: stroke_purge(this, msg, out); break; + case STR_LEASES: + stroke_leases(this, msg, out); + break; default: DBG1(DBG_CFG, "received unknown stroke"); break; @@ -621,7 +636,7 @@ stroke_socket_t *stroke_socket_create() this->ca = stroke_ca_create(this->cred); this->config = stroke_config_create(this->ca, this->cred); this->control = stroke_control_create(); - this->list = stroke_list_create(); + this->list = stroke_list_create(this->attribute); charon->credentials->add_set(charon->credentials, &this->ca->set); charon->credentials->add_set(charon->credentials, &this->cred->set); |