diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-03-08 15:45:41 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-05-23 18:46:49 +0200 |
commit | d80055baae6719a28fe1ec872e35086dd3f23870 (patch) | |
tree | bcac5ddd5c96fb6f93ecf757d4615d8ee01caafc | |
parent | 44107cb7b75551e02afd56061534495c10b94de3 (diff) | |
download | strongswan-d80055baae6719a28fe1ec872e35086dd3f23870.tar.bz2 strongswan-d80055baae6719a28fe1ec872e35086dd3f23870.tar.xz |
unit-tests: Keep track of installed IPsec SAs in mock kernel_ipsec_t implementation
-rw-r--r-- | src/libcharon/tests/utils/mock_ipsec.c | 129 | ||||
-rw-r--r-- | src/libcharon/tests/utils/mock_ipsec.h | 11 |
2 files changed, 136 insertions, 4 deletions
diff --git a/src/libcharon/tests/utils/mock_ipsec.c b/src/libcharon/tests/utils/mock_ipsec.c index d57a26a87..c11f5c966 100644 --- a/src/libcharon/tests/utils/mock_ipsec.c +++ b/src/libcharon/tests/utils/mock_ipsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * Copyright (C) 2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -16,6 +16,11 @@ #include "mock_ipsec.h" +#include <daemon.h> +#include <collections/hashtable.h> + +#include <assert.h> + typedef struct private_kernel_ipsec_t private_kernel_ipsec_t; /** @@ -32,13 +37,72 @@ struct private_kernel_ipsec_t { * Allocated SPI */ refcount_t spi; + + /** + * Installed SAs + */ + hashtable_t *sas; }; +/** + * Global instance + */ +static private_kernel_ipsec_t *instance; + +/** + * Data about installed IPsec SAs + */ +typedef struct { + /** + * SPI of the SA + */ + uint32_t spi; + + /** + * Associated IKE_SA + */ + ike_sa_t *ike_sa; + + /** + * TRUE if this was an allocated SPI + */ + bool alloc; + +} entry_t; + +/** + * Hash an IPsec SA entry + */ +static u_int entry_hash(const void *key) +{ + entry_t *entry = (entry_t*)key; + return chunk_hash_inc(chunk_from_thing(entry->spi), + chunk_hash(chunk_from_thing(entry->ike_sa))); +} + +/** + * Compare an IPsec SA entry + */ +static bool entry_equals(const void *key, const void *other_key) +{ + entry_t *a = (entry_t*)key, *b = (entry_t*)other_key; + return a->spi == b->spi && a->ike_sa == b->ike_sa; +} + METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint8_t protocol, uint32_t *spi) { + entry_t *entry; + *spi = (uint32_t)ref_get(&this->spi); + INIT(entry, + .spi = *spi, + .ike_sa = charon->bus->get_sa(charon->bus), + .alloc = TRUE, + ); + entry = this->sas->put(this->sas, entry, entry); + assert(!entry); return SUCCESS; } @@ -52,6 +116,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { + entry_t *entry; + + INIT(entry, + .spi = id->spi, + .ike_sa = charon->bus->get_sa(charon->bus), + ); + if (data->inbound) + { + entry = this->sas->put(this->sas, entry, entry); + assert(entry && entry->alloc); + free(entry); + } + else + { + entry = this->sas->put(this->sas, entry, entry); + assert(!entry); + } return SUCCESS; } @@ -74,6 +155,14 @@ METHOD(kernel_ipsec_t, del_sa, status_t, private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_del_sa_t *data) { + entry_t *entry, lookup = { + .spi = id->spi, + .ike_sa = charon->bus->get_sa(charon->bus), + }; + + entry = this->sas->remove(this->sas, &lookup); + assert(entry); + free(entry); return SUCCESS; } @@ -99,6 +188,13 @@ METHOD(kernel_ipsec_t, del_policy, status_t, return SUCCESS; } +METHOD(kernel_ipsec_t, destroy, void, + private_kernel_ipsec_t *this) +{ + this->sas->destroy(this->sas); + free(this); +} + /* * Described in header */ @@ -121,8 +217,37 @@ kernel_ipsec_t *mock_ipsec_create() .flush_policies = (void*)return_failed, .bypass_socket = (void*)return_true, .enable_udp_decap = (void*)return_true, - .destroy = (void*)free, + .destroy = _destroy, }, + .sas = hashtable_create(entry_hash, entry_equals, 8), ); + + instance = this; + return &this->public; } + +/** + * Filter SAs + */ +static bool filter_sas(void *data, entry_t **entry, ike_sa_t **ike_sa, + void *unused, uint32_t *spi) +{ + if ((*entry)->alloc) + { + return FALSE; + } + *ike_sa = (*entry)->ike_sa; + *spi = (*entry)->spi; + return TRUE; +} + +/* + * Described in header + */ +enumerator_t *mock_ipsec_create_sa_enumerator() +{ + return enumerator_create_filter( + instance->sas->create_enumerator(instance->sas), + (void*)filter_sas, NULL, NULL); +} diff --git a/src/libcharon/tests/utils/mock_ipsec.h b/src/libcharon/tests/utils/mock_ipsec.h index cbf21524a..95038a561 100644 --- a/src/libcharon/tests/utils/mock_ipsec.h +++ b/src/libcharon/tests/utils/mock_ipsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,7 +15,7 @@ /** * kernel_ipsec_t implementation used for exchange unit tests. Currently - * returns sequential SPIs, all other methods are noops. + * returns sequential SPIs, and keeps track of installed SAs. * * @defgroup mock_ipsec mock_ipsec * @{ @ingroup test_utils_c @@ -33,4 +33,11 @@ */ kernel_ipsec_t *mock_ipsec_create(); +/** + * Enumerate the installed SAs + * + * @return enumerator over (ike_sa_t*, uint32_t) + */ +enumerator_t *mock_ipsec_create_sa_enumerator(); + #endif /** MOCK_IPSEC_H_ @}*/ |