Improved the management of soap request/response.

The director has the opportunity to change the configuration of AC in join
connection. The virtual interfaces which encapsulate the wifi stations is
managed dynamically by the Director.
The AC must request authorization from Director for associate a station.
This commit is contained in:
vemax78
2014-10-19 21:37:22 +02:00
parent 63f5fcea19
commit 8937ded1d3
24 changed files with 1049 additions and 549 deletions

View File

@ -5,13 +5,11 @@
static void capwap_hash_free_item(struct capwap_hash* hash, struct capwap_hash_item* item) {
ASSERT(hash != NULL);
ASSERT(item != NULL);
ASSERT(item->key != NULL);
if (item->data && hash->item_free) {
hash->item_free(item->key, hash->keysize, item->data);
hash->item_free(item->data);
}
capwap_free(item->key);
capwap_free(item);
}
@ -43,7 +41,7 @@ static struct capwap_hash_item* capwap_hash_search_items(struct capwap_hash* has
search = item;
while (search) {
result = hash->item_cmp(key, search->key, hash->keysize);
result = hash->item_cmp(key, hash->item_getkey(search->data));
if (!result) {
return search;
@ -59,44 +57,57 @@ static struct capwap_hash_item* capwap_hash_search_items(struct capwap_hash* has
/* */
static int capwap_hash_foreach_items(struct capwap_hash* hash, struct capwap_hash_item* item, capwap_hash_item_foreach item_foreach, void* param) {
int result;
ASSERT(hash != NULL);
ASSERT(item_foreach != NULL);
ASSERT(item != NULL);
/* */
if (item->left) {
if (!capwap_hash_foreach_items(hash, item->left, item_foreach, param)) {
return 0;
result = capwap_hash_foreach_items(hash, item->left, item_foreach, param);
if (result == HASH_BREAK) {
return HASH_BREAK;
}
}
/* */
if (!item_foreach(item->key, hash->keysize, item->data, param)) {
return 0;
item->removenext = NULL;
result = item_foreach(item->data, param);
/* Delete item */
if ((result == HASH_DELETE_AND_BREAK) || (result == HASH_DELETE_AND_CONTINUE)) {
item->removenext = hash->removeitems;
hash->removeitems = item;
}
/* Break */
if ((result == HASH_BREAK) || (result == HASH_DELETE_AND_BREAK)) {
return HASH_BREAK;
}
/* */
if (item->right) {
if (!capwap_hash_foreach_items(hash, item->right, item_foreach, param)) {
return 0;
result = capwap_hash_foreach_items(hash, item->right, item_foreach, param);
if (result == HASH_BREAK) {
return HASH_BREAK;
}
}
return 1;
return HASH_CONTINUE;
}
/* */
static struct capwap_hash_item* capwap_hash_create_item(struct capwap_hash* hash, const void* key, void* data) {
static struct capwap_hash_item* capwap_hash_create_item(struct capwap_hash* hash, void* data) {
struct capwap_hash_item* item;
ASSERT(hash != NULL);
ASSERT(key != NULL);
ASSERT(data != NULL);
/* */
item = (struct capwap_hash_item*)capwap_alloc(sizeof(struct capwap_hash_item));
memset(item, 0, sizeof(struct capwap_hash_item));
item->key = capwap_clone(key, hash->keysize);
item->data = data;
return item;
@ -243,132 +254,13 @@ static void capwap_hash_balance_tree(struct capwap_hash_item* item, struct capwa
}
/* */
static int capwap_hash_item_memcmp(const void* key1, const void* key2, unsigned long keysize) {
return memcmp(key1, key2, keysize);
}
/* */
struct capwap_hash* capwap_hash_create(unsigned long hashsize, unsigned long keysize, capwap_hash_item_gethash item_hash, capwap_hash_item_cmp item_cmp, capwap_hash_item_free item_free) {
unsigned long size;
struct capwap_hash* hash;
ASSERT(hashsize > 0);
ASSERT(keysize > 0);
ASSERT(item_hash != NULL);
size = sizeof(struct capwap_hash_item*) * hashsize;
/* */
hash = (struct capwap_hash*)capwap_alloc(sizeof(struct capwap_hash));
hash->hashsize = hashsize;
hash->keysize = keysize;
hash->count = 0;
hash->items = (struct capwap_hash_item**)capwap_alloc(size);
memset(hash->items, 0, size);
hash->item_hash = item_hash;
hash->item_cmp = (item_cmp ? item_cmp : capwap_hash_item_memcmp);
hash->item_free = item_free;
return hash;
}
/* */
void capwap_hash_free(struct capwap_hash* hash) {
ASSERT(hash != NULL);
/* Delete all items */
capwap_hash_deleteall(hash);
/* Free */
capwap_free(hash->items);
capwap_free(hash);
}
/* */
void capwap_hash_add(struct capwap_hash* hash, const void* key, void* data) {
int result;
unsigned long hashvalue;
struct capwap_hash_item* search;
struct capwap_hash_item* item = NULL;
ASSERT(hash != NULL);
ASSERT(key != NULL);
/* */
hashvalue = hash->item_hash(key, hash->keysize, hash->hashsize);
ASSERT(hashvalue < hash->hashsize);
/* Search position where insert item */
search = hash->items[hashvalue];
if (!search) {
hash->count++;
hash->items[hashvalue] = capwap_hash_create_item(hash, key, data);
} else {
while (search) {
result = hash->item_cmp(key, search->key, hash->keysize);
if (!result) {
/* Free old element and update data value without create new item */
if (search->data && hash->item_free) {
hash->item_free(search->key, hash->keysize, search->data);
}
search->data = data;
break;
} else if (result < 0) {
if (search->left) {
search = search->left;
} else {
hash->count++;
item = capwap_hash_create_item(hash, key, data);
capwap_hash_set_left_item(search, item);
break;
}
} else if (result > 0) {
if (search->right) {
search = search->right;
} else {
hash->count++;
item = capwap_hash_create_item(hash, key, data);
capwap_hash_set_right_item(search, item);
break;
}
}
}
/* Rebalancing tree */
while (item) {
capwap_hash_update_height(item);
capwap_hash_balance_tree(item, &hash->items[hashvalue]);
/* Rebalancing parent */
item = item->parent;
}
}
}
/* */
void capwap_hash_delete(struct capwap_hash* hash, const void* key) {
unsigned long hashvalue;
struct capwap_hash_item* search;
static void capwap_hash_deleteitem(struct capwap_hash* hash, const void* key, struct capwap_hash_item* search, unsigned long hashvalue) {
struct capwap_hash_item* parent;
ASSERT(hash != NULL);
ASSERT(key != NULL);
/* */
hashvalue = hash->item_hash(key, hash->keysize, hash->hashsize);
if (!hash->items[hashvalue]) {
return;
}
/* */
search = capwap_hash_search_items(hash, hash->items[hashvalue], key);
if (!search) {
return;
}
/* */
ASSERT(hash->count > 0);
ASSERT(search != NULL);
ASSERT(hashvalue < hash->hashsize);
/* Rebalancing tree */
parent = search->parent;
@ -465,6 +357,129 @@ void capwap_hash_delete(struct capwap_hash* hash, const void* key) {
capwap_hash_free_item(hash, search);
}
/* */
struct capwap_hash* capwap_hash_create(unsigned long hashsize) {
unsigned long size;
struct capwap_hash* hash;
ASSERT(hashsize > 0);
/* */
hash = (struct capwap_hash*)capwap_alloc(sizeof(struct capwap_hash));
hash->hashsize = hashsize;
hash->count = 0;
size = sizeof(struct capwap_hash_item*) * hashsize;
hash->items = (struct capwap_hash_item**)capwap_alloc(size);
memset(hash->items, 0, size);
return hash;
}
/* */
void capwap_hash_free(struct capwap_hash* hash) {
ASSERT(hash != NULL);
/* Delete all items */
capwap_hash_deleteall(hash);
/* Free */
capwap_free(hash->items);
capwap_free(hash);
}
/* */
void capwap_hash_add(struct capwap_hash* hash, void* data) {
int result;
const void* key;
unsigned long hashvalue;
struct capwap_hash_item* search;
struct capwap_hash_item* item = NULL;
ASSERT(data != NULL);
ASSERT(hash != NULL);
ASSERT(hash->item_gethash != NULL);
ASSERT(hash->item_getkey != NULL);
ASSERT(hash->item_cmp != NULL);
/* */
key = hash->item_getkey(data);
hashvalue = hash->item_gethash(key, hash->hashsize);
ASSERT(hashvalue < hash->hashsize);
/* Search position where insert item */
search = hash->items[hashvalue];
if (!search) {
hash->count++;
hash->items[hashvalue] = capwap_hash_create_item(hash, data);
} else {
while (search) {
result = hash->item_cmp(key, hash->item_getkey(search->data));
if (!result) {
/* Free old element and update data value without create new item */
if (search->data && hash->item_free) {
hash->item_free(search->data);
}
search->data = data;
break;
} else if (result < 0) {
if (search->left) {
search = search->left;
} else {
hash->count++;
item = capwap_hash_create_item(hash, data);
capwap_hash_set_left_item(search, item);
break;
}
} else if (result > 0) {
if (search->right) {
search = search->right;
} else {
hash->count++;
item = capwap_hash_create_item(hash, data);
capwap_hash_set_right_item(search, item);
break;
}
}
}
/* Rebalancing tree */
while (item) {
capwap_hash_update_height(item);
capwap_hash_balance_tree(item, &hash->items[hashvalue]);
/* Rebalancing parent */
item = item->parent;
}
}
}
/* */
void capwap_hash_delete(struct capwap_hash* hash, const void* key) {
unsigned long hashvalue;
struct capwap_hash_item* search;
ASSERT(hash != NULL);
ASSERT(key != NULL);
/* */
hashvalue = hash->item_gethash(key, hash->hashsize);
ASSERT(hashvalue < hash->hashsize);
if (!hash->items[hashvalue]) {
return;
}
/* */
search = capwap_hash_search_items(hash, hash->items[hashvalue], key);
if (!search) {
return;
}
/* */
capwap_hash_deleteitem(hash, key, search, hashvalue);
}
/* */
void capwap_hash_deleteall(struct capwap_hash* hash) {
unsigned long i;
@ -482,27 +497,6 @@ void capwap_hash_deleteall(struct capwap_hash* hash) {
hash->count = 0;
}
/* */
int capwap_hash_hasitem(struct capwap_hash* hash, const void* key) {
unsigned long hashvalue;
struct capwap_hash_item* items;
struct capwap_hash_item* result;
ASSERT(hash != NULL);
ASSERT(key != NULL);
/* Search item */
hashvalue = hash->item_hash(key, hash->keysize, hash->hashsize);
items = hash->items[hashvalue];
if (!items) {
return 0;
}
/* */
result = capwap_hash_search_items(hash, items, key);
return (result ? 1 : 0);
}
/* */
void* capwap_hash_search(struct capwap_hash* hash, const void* key) {
unsigned long hashvalue;
@ -513,7 +507,7 @@ void* capwap_hash_search(struct capwap_hash* hash, const void* key) {
ASSERT(key != NULL);
/* Search item */
hashvalue = hash->item_hash(key, hash->keysize, hash->hashsize);
hashvalue = hash->item_gethash(key, hash->hashsize);
items = hash->items[hashvalue];
if (!items) {
return NULL;
@ -530,14 +524,32 @@ void* capwap_hash_search(struct capwap_hash* hash, const void* key) {
/* */
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param) {
int result;
unsigned long i;
ASSERT(hash != NULL);
ASSERT(item_foreach != NULL);
/* */
hash->removeitems = NULL;
/* */
for (i = 0; i < hash->hashsize; i++) {
if (hash->items[i]) {
capwap_hash_foreach_items(hash, hash->items[i], item_foreach, param);
result = capwap_hash_foreach_items(hash, hash->items[i], item_foreach, param);
if (result == HASH_BREAK) {
break;
}
}
}
/* Delete marked items */
while (hash->removeitems) {
struct capwap_hash_item* item = hash->removeitems;
const void* key = hash->item_getkey(item->data);
/* */
hash->removeitems = item->removenext;
capwap_hash_deleteitem(hash, key, item, hash->item_gethash(key, hash->hashsize));
}
}

View File

@ -1,14 +1,18 @@
#ifndef __CAPWAP_HASH_HEADER__
#define __CAPWAP_HASH_HEADER__
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long keysize, unsigned long hashsize);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2, unsigned long keysize);
typedef void (*capwap_hash_item_free)(const void* key, unsigned long keysize, void* data);
typedef unsigned long (*capwap_hash_item_gethash)(const void* key, unsigned long hashsize);
typedef const void* (*capwap_hash_item_getkey)(const void* data);
typedef int (*capwap_hash_item_cmp)(const void* key1, const void* key2);
typedef void (*capwap_hash_item_free)(void* data);
typedef int (*capwap_hash_item_foreach)(const void* key, unsigned long keysize, void* data, void* param);
#define HASH_BREAK 0
#define HASH_CONTINUE 1
#define HASH_DELETE_AND_BREAK 2
#define HASH_DELETE_AND_CONTINUE 3
typedef int (*capwap_hash_item_foreach)(void* data, void* param);
struct capwap_hash_item {
void* key;
void* data;
int height;
@ -16,30 +20,34 @@ struct capwap_hash_item {
struct capwap_hash_item* parent;
struct capwap_hash_item* left;
struct capwap_hash_item* right;
struct capwap_hash_item* removenext;
};
struct capwap_hash {
struct capwap_hash_item** items;
unsigned long hashsize;
unsigned long keysize;
/* */
unsigned long count;
/* */
struct capwap_hash_item* removeitems;
/* Callback functions */
capwap_hash_item_gethash item_hash;
capwap_hash_item_gethash item_gethash;
capwap_hash_item_getkey item_getkey;
capwap_hash_item_cmp item_cmp;
capwap_hash_item_free item_free;
};
struct capwap_hash* capwap_hash_create(unsigned long hashsize, unsigned long keysize, capwap_hash_item_gethash item_hash, capwap_hash_item_cmp item_cmp, capwap_hash_item_free item_free);
struct capwap_hash* capwap_hash_create(unsigned long hashsize);
void capwap_hash_free(struct capwap_hash* hash);
void capwap_hash_add(struct capwap_hash* hash, const void* key, void* data);
void capwap_hash_add(struct capwap_hash* hash, void* data);
void capwap_hash_delete(struct capwap_hash* hash, const void* key);
void capwap_hash_deleteall(struct capwap_hash* hash);
int capwap_hash_hasitem(struct capwap_hash* hash, const void* key);
void* capwap_hash_search(struct capwap_hash* hash, const void* key);
void capwap_hash_foreach(struct capwap_hash* hash, capwap_hash_item_foreach item_foreach, void* param);

View File

@ -38,7 +38,7 @@ void capwap_rwlock_wrlock(capwap_rwlock_t* lock) {
}
/* */
void capwap_rwlock_exit(capwap_rwlock_t* lock) {
void capwap_rwlock_unlock(capwap_rwlock_t* lock) {
ASSERT(lock != NULL);
pthread_rwlock_unlock(&lock->rwlock);

View File

@ -13,7 +13,7 @@ int capwap_rwlock_init(capwap_rwlock_t* lock);
void capwap_rwlock_destroy(capwap_rwlock_t* lock);
void capwap_rwlock_rdlock(capwap_rwlock_t* lock);
void capwap_rwlock_wrlock(capwap_rwlock_t* lock);
void capwap_rwlock_exit(capwap_rwlock_t* lock);
void capwap_rwlock_unlock(capwap_rwlock_t* lock);
#endif /* CAPWAP_MULTITHREADING_ENABLE */

View File

@ -7,12 +7,17 @@
/* #define CAPWAP_TIMEOUT_LOGGING_DEBUG 1 */
/* */
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long keysize, unsigned long hashsize) {
return (*(unsigned long*)key % hashsize);
static unsigned long capwap_timeout_hash_item_gethash(const void* key, unsigned long hashsize) {
return (*((unsigned long*)key) % hashsize);
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2, unsigned long keysize) {
static const void* capwap_timeout_hash_item_getkey(const void* data) {
return (const void*)&((struct capwap_timeout_item*)((struct capwap_list_item*)data)->item)->index;
}
/* */
static int capwap_timeout_hash_item_cmp(const void* key1, const void* key2) {
unsigned long value1 = *(unsigned long*)key1;
unsigned long value2 = *(unsigned long*)key2;
@ -101,7 +106,11 @@ struct capwap_timeout* capwap_timeout_init(void) {
memset(timeout, 0, sizeof(struct capwap_timeout));
/* */
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT, sizeof(unsigned long), capwap_timeout_hash_item_gethash, capwap_timeout_hash_item_cmp, NULL);
timeout->itemsreference = capwap_hash_create(CAPWAP_TIMEOUT_HASH_COUNT);
timeout->itemsreference->item_gethash = capwap_timeout_hash_item_gethash;
timeout->itemsreference->item_getkey = capwap_timeout_hash_item_getkey;
timeout->itemsreference->item_cmp = capwap_timeout_hash_item_cmp;
timeout->itemstimeout = capwap_list_create();
return timeout;
@ -204,7 +213,7 @@ unsigned long capwap_timeout_set(struct capwap_timeout* timeout, unsigned long i
#endif
/* Add itemlist into hash for rapid searching */
capwap_hash_add(timeout->itemsreference, (const void*)&item->index, (void*)itemlist);
capwap_hash_add(timeout->itemsreference, (void*)itemlist);
/* Add itemlist into order list */
capwap_timeout_additem(timeout->itemstimeout, itemlist);