redirect-manager: Add manager for redirect providers
This commit is contained in:
@@ -84,7 +84,7 @@ sa/child_sa_manager.c sa/child_sa_manager.h \
|
||||
sa/task_manager.h sa/task_manager.c \
|
||||
sa/shunt_manager.c sa/shunt_manager.h \
|
||||
sa/trap_manager.c sa/trap_manager.h \
|
||||
sa/redirect_provider.h \
|
||||
sa/redirect_provider.h sa/redirect_manager.c sa/redirect_manager.h \
|
||||
sa/task.c sa/task.h
|
||||
|
||||
libcharon_la_SOURCES += \
|
||||
|
||||
@@ -83,7 +83,7 @@ sa/child_sa_manager.c sa/child_sa_manager.h \
|
||||
sa/task_manager.h sa/task_manager.c \
|
||||
sa/shunt_manager.c sa/shunt_manager.h \
|
||||
sa/trap_manager.c sa/trap_manager.h \
|
||||
sa/redirect_provider.h \
|
||||
sa/redirect_provider.h sa/redirect_manager.c sa/redirect_manager.h \
|
||||
sa/task.c sa/task.h
|
||||
|
||||
if USE_IKEV2
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "redirect_manager.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
typedef struct private_redirect_manager_t private_redirect_manager_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_redirect_manager_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
redirect_manager_t public;
|
||||
|
||||
/**
|
||||
* Registered providers
|
||||
*/
|
||||
linked_list_t *providers;
|
||||
|
||||
/**
|
||||
* Lock to access list of providers
|
||||
*/
|
||||
rwlock_t *lock;
|
||||
};
|
||||
|
||||
METHOD(redirect_manager_t, add_provider, void,
|
||||
private_redirect_manager_t *this, redirect_provider_t *provider)
|
||||
{
|
||||
this->lock->write_lock(this->lock);
|
||||
this->providers->insert_last(this->providers, provider);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(redirect_manager_t, remove_provider, void,
|
||||
private_redirect_manager_t *this, redirect_provider_t *provider)
|
||||
{
|
||||
this->lock->write_lock(this->lock);
|
||||
this->providers->remove(this->providers, provider, NULL);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a client should be redirected using the callback with the
|
||||
* given offset into the redirect_provider_t interface.
|
||||
*/
|
||||
static bool should_redirect(private_redirect_manager_t *this, ike_sa_t *ike_sa,
|
||||
identification_t **gateway, size_t offset)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
void *provider;
|
||||
bool redirect = FALSE;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->providers->create_enumerator(this->providers);
|
||||
while (enumerator->enumerate(enumerator, &provider))
|
||||
{
|
||||
bool (**method)(void*,ike_sa_t*,identification_t**) = provider + offset;
|
||||
if (*method && (*method)(provider, ike_sa, gateway))
|
||||
{
|
||||
redirect = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return redirect;
|
||||
}
|
||||
|
||||
METHOD(redirect_manager_t, redirect_on_init, bool,
|
||||
private_redirect_manager_t *this, ike_sa_t *ike_sa,
|
||||
identification_t **gateway)
|
||||
{
|
||||
return should_redirect(this, ike_sa, gateway,
|
||||
offsetof(redirect_provider_t, redirect_on_init));
|
||||
}
|
||||
|
||||
METHOD(redirect_manager_t, redirect_on_auth, bool,
|
||||
private_redirect_manager_t *this, ike_sa_t *ike_sa,
|
||||
identification_t **gateway)
|
||||
{
|
||||
return should_redirect(this, ike_sa, gateway,
|
||||
offsetof(redirect_provider_t, redirect_on_auth));
|
||||
}
|
||||
|
||||
METHOD(redirect_manager_t, destroy, void,
|
||||
private_redirect_manager_t *this)
|
||||
{
|
||||
this->providers->destroy(this->providers);
|
||||
this->lock->destroy(this->lock);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
redirect_manager_t *redirect_manager_create()
|
||||
{
|
||||
private_redirect_manager_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add_provider = _add_provider,
|
||||
.remove_provider = _remove_provider,
|
||||
.redirect_on_init = _redirect_on_init,
|
||||
.redirect_on_auth = _redirect_on_auth,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.providers = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup redirect_manager redirect_manager
|
||||
* @{ @ingroup sa
|
||||
*/
|
||||
|
||||
#ifndef REDIRECT_MANAGER_H_
|
||||
#define REDIRECT_MANAGER_H_
|
||||
|
||||
typedef struct redirect_manager_t redirect_manager_t;
|
||||
|
||||
#include <sa/redirect_provider.h>
|
||||
|
||||
/**
|
||||
* Manages redirect providers.
|
||||
*/
|
||||
struct redirect_manager_t {
|
||||
|
||||
/**
|
||||
* Add a redirect provider.
|
||||
*
|
||||
* All registered providers are queried until one of them decides to
|
||||
* redirect a client.
|
||||
*
|
||||
* A provider may be called concurrently for different IKE_SAs.
|
||||
*
|
||||
* @param provider provider to register
|
||||
*/
|
||||
void (*add_provider)(redirect_manager_t *this,
|
||||
redirect_provider_t *provider);
|
||||
|
||||
/**
|
||||
* Remove a redirect provider.
|
||||
*
|
||||
* @param provider provider to unregister
|
||||
*/
|
||||
void (*remove_provider)(redirect_manager_t *this,
|
||||
redirect_provider_t *provider);
|
||||
|
||||
/**
|
||||
* Determine whether a client should be redirected upon receipt of the
|
||||
* IKE_SA_INIT message.
|
||||
*
|
||||
* @param ike_sa IKE_SA for which this is called
|
||||
* @param gateway[out] new IKE gateway (IP or FQDN)
|
||||
* @return TRUE if client should be redirected, FALSE otherwise
|
||||
*/
|
||||
bool (*redirect_on_init)(redirect_manager_t *this, ike_sa_t *ike_sa,
|
||||
identification_t **gateway);
|
||||
|
||||
/**
|
||||
* Determine whether a client should be redirected after the IKE_AUTH has
|
||||
* been handled. Should be called after the client is authenticated and
|
||||
* when the server authenticates itself.
|
||||
*
|
||||
* @param ike_sa IKE_SA for which this is called
|
||||
* @param gateway[out] new IKE gateway (IP or FQDN)
|
||||
* @return TRUE if client should be redirected, FALSE otherwise
|
||||
*/
|
||||
bool (*redirect_on_auth)(redirect_manager_t *this, ike_sa_t *ike_sa,
|
||||
identification_t **gateway);
|
||||
|
||||
/**
|
||||
* Destroy this instance.
|
||||
*/
|
||||
void (*destroy)(redirect_manager_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a redirect manager instance.
|
||||
*
|
||||
* @return manager instance
|
||||
*/
|
||||
redirect_manager_t *redirect_manager_create();
|
||||
|
||||
#endif /** REDIRECT_MANAGER_H_ @}*/
|
||||
Reference in New Issue
Block a user