enabling acquire for mediated connections

This commit is contained in:
Tobias Brunner
2008-04-10 12:51:04 +00:00
parent 78abba428f
commit 4a6474c2c3
6 changed files with 51 additions and 146 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2007 Tobias Brunner * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -37,11 +37,6 @@ struct private_initiate_mediation_job_t {
*/ */
ike_sa_id_t *mediated_sa_id; ike_sa_id_t *mediated_sa_id;
/**
* Child config of the CHILD_SA of the mediated connection.
*/
child_cfg_t *mediated_child;
/** /**
* ID of the IKE_SA of the mediation connection. * ID of the IKE_SA of the mediation connection.
*/ */
@@ -55,7 +50,6 @@ static void destroy(private_initiate_mediation_job_t *this)
{ {
DESTROY_IF(this->mediation_sa_id); DESTROY_IF(this->mediation_sa_id);
DESTROY_IF(this->mediated_sa_id); DESTROY_IF(this->mediated_sa_id);
DESTROY_IF(this->mediated_child);
free(this); free(this);
} }
@@ -99,7 +93,7 @@ static void initiate(private_initiate_mediation_job_t *this)
if (charon->connect_manager->check_and_register(charon->connect_manager, if (charon->connect_manager->check_and_register(charon->connect_manager,
mediation_cfg->get_my_id(mediation_cfg), mediation_cfg->get_my_id(mediation_cfg),
mediated_cfg->get_peer_id(mediated_cfg), mediated_cfg->get_peer_id(mediated_cfg),
this->mediated_sa_id, this->mediated_child)) this->mediated_sa_id))
{ {
mediated_cfg->destroy(mediated_cfg); mediated_cfg->destroy(mediated_cfg);
mediation_cfg->destroy(mediation_cfg); mediation_cfg->destroy(mediation_cfg);
@@ -211,7 +205,6 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
/* private variables */ /* private variables */
this->mediation_sa_id = NULL; this->mediation_sa_id = NULL;
this->mediated_sa_id = NULL; this->mediated_sa_id = NULL;
this->mediated_child = NULL;
return this; return this;
} }
@@ -219,16 +212,13 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
/* /*
* Described in header * Described in header
*/ */
initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id, initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
child_cfg_t *child_cfg)
{ {
private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty(); private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
this->public.job_interface.execute = (void (*) (job_t *)) initiate; this->public.job_interface.execute = (void (*) (job_t *)) initiate;
this->mediated_sa_id = ike_sa_id->clone(ike_sa_id); this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
child_cfg->get_ref(child_cfg);
this->mediated_child = child_cfg;
return &this->public; return &this->public;
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2007 Tobias Brunner * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
typedef struct initiate_mediation_job_t initiate_mediation_job_t; typedef struct initiate_mediation_job_t initiate_mediation_job_t;
#include <processing/jobs/job.h> #include <processing/jobs/job.h>
#include <config/child_cfg.h>
#include <sa/ike_sa_id.h> #include <sa/ike_sa_id.h>
/** /**
@@ -46,11 +45,9 @@ struct initiate_mediation_job_t {
* Creates a job of type INITIATE_MEDIATION. * Creates a job of type INITIATE_MEDIATION.
* *
* @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned) * @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
* @param child_cfg child config of the child_sa (gets cloned)
* @return job object * @return job object
*/ */
initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id, initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id);
child_cfg_t *child_cfg);
/** /**
* Creates a special job of type INITIATE_MEDIATION that reinitiates a * Creates a special job of type INITIATE_MEDIATION that reinitiates a
+11 -69
View File
@@ -255,43 +255,6 @@ static check_list_t *check_list_create(identification_t *initiator, identificati
return this; return this;
} }
typedef struct waiting_sa_t waiting_sa_t;
/**
* For an initiator, the data stored about a waiting mediated sa
*/
struct waiting_sa_t {
/** ike sa id */
ike_sa_id_t *ike_sa_id;
/** list of child_cfg_t */
linked_list_t *childs;
};
/**
* Destroys a queued mediated sa
*/
static void waiting_sa_destroy(waiting_sa_t *this)
{
DESTROY_IF(this->ike_sa_id);
this->childs->destroy_offset(this->childs, offsetof(child_cfg_t, destroy));
free(this);
}
/**
* Creates a new mediated sa object
*/
static waiting_sa_t *waiting_sa_create(ike_sa_id_t *ike_sa_id)
{
waiting_sa_t *this = malloc_thing(waiting_sa_t);
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->childs = linked_list_create();
return this;
}
typedef struct initiated_t initiated_t; typedef struct initiated_t initiated_t;
/** /**
@@ -315,7 +278,7 @@ static void initiated_destroy(initiated_t *this)
{ {
DESTROY_IF(this->id); DESTROY_IF(this->id);
DESTROY_IF(this->peer_id); DESTROY_IF(this->peer_id);
this->mediated->destroy_function(this->mediated, (void*)waiting_sa_destroy); this->mediated->destroy_offset(this->mediated, offsetof(ike_sa_id_t, destroy));
free(this); free(this);
} }
@@ -517,21 +480,6 @@ static void remove_initiated(private_connect_manager_t *this, initiated_t *initi
iterator->destroy(iterator); iterator->destroy(iterator);
} }
/**
* Finds a waiting sa
*/
static bool match_waiting_sa(waiting_sa_t *current, ike_sa_id_t *ike_sa_id)
{
return ike_sa_id->equals(ike_sa_id, current->ike_sa_id);
}
static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa)
{
return initiated->mediated->find_first(initiated->mediated,
(linked_list_match_t)match_waiting_sa,
(void**)waiting_sa, ike_sa_id);
}
/** /**
* Find the checklist with a specific connect ID * Find the checklist with a specific connect ID
*/ */
@@ -1205,13 +1153,12 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
endpoint_pair_t *pair; endpoint_pair_t *pair;
if (get_best_valid_pair(checklist, &pair) == SUCCESS) if (get_best_valid_pair(checklist, &pair) == SUCCESS)
{ {
waiting_sa_t *waiting_sa; ike_sa_id_t *waiting_sa;
iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE); iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
while (iterator->iterate(iterator, (void**)&waiting_sa)) while (iterator->iterate(iterator, (void**)&waiting_sa))
{ {
ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa->ike_sa_id); ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa);
if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs, if (sa->initiate_mediated(sa, pair->local, pair->remote, checklist->connect_id) != SUCCESS)
checklist->connect_id) != SUCCESS)
{ {
SIG(IKE_UP_FAILED, "establishing the mediated connection failed"); SIG(IKE_UP_FAILED, "establishing the mediated connection failed");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
@@ -1440,7 +1387,7 @@ static void process_check(private_connect_manager_t *this, message_t *message)
*/ */
static bool check_and_register(private_connect_manager_t *this, static bool check_and_register(private_connect_manager_t *this,
identification_t *id, identification_t *peer_id, identification_t *id, identification_t *peer_id,
ike_sa_id_t *mediated_sa, child_cfg_t *child) ike_sa_id_t *mediated_sa)
{ {
initiated_t *initiated; initiated_t *initiated;
bool already_there = TRUE; bool already_there = TRUE;
@@ -1455,16 +1402,12 @@ static bool check_and_register(private_connect_manager_t *this,
already_there = FALSE; already_there = FALSE;
} }
waiting_sa_t *waiting_sa; if (initiated->mediated->find_first(initiated->mediated,
if (get_waiting_sa(initiated, mediated_sa, &waiting_sa) != SUCCESS) (linked_list_match_t)mediated_sa->equals, NULL, mediated_sa) != SUCCESS)
{ {
waiting_sa = waiting_sa_create(mediated_sa); initiated->mediated->insert_last(initiated->mediated, mediated_sa->clone(mediated_sa));
initiated->mediated->insert_last(initiated->mediated, waiting_sa);
} }
child->get_ref(child);
waiting_sa->childs->insert_last(waiting_sa->childs, child);
pthread_mutex_unlock(&(this->mutex)); pthread_mutex_unlock(&(this->mutex));
return already_there; return already_there;
@@ -1487,12 +1430,11 @@ static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *med
return; return;
} }
waiting_sa_t *waiting_sa; ike_sa_id_t *waiting_sa;
iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE); iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
while (iterator->iterate(iterator, (void**)&waiting_sa)) while (iterator->iterate(iterator, (void**)&waiting_sa))
{ {
job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, waiting_sa);
waiting_sa->ike_sa_id);
charon->processor->queue_job(charon->processor, job); charon->processor->queue_job(charon->processor, job);
} }
iterator->destroy(iterator); iterator->destroy(iterator);
@@ -1610,7 +1552,7 @@ connect_manager_t *connect_manager_create()
private_connect_manager_t *this = malloc_thing(private_connect_manager_t); private_connect_manager_t *this = malloc_thing(private_connect_manager_t);
this->public.destroy = (void(*)(connect_manager_t*))destroy; this->public.destroy = (void(*)(connect_manager_t*))destroy;
this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*,child_cfg_t*))check_and_register; this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*))check_and_register;
this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate; this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate;
this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data; this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data;
this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data; this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
+1 -4
View File
@@ -26,7 +26,6 @@
typedef struct connect_manager_t connect_manager_t; typedef struct connect_manager_t connect_manager_t;
#include <encoding/message.h> #include <encoding/message.h>
#include <config/child_cfg.h>
#include <sa/ike_sa_id.h> #include <sa/ike_sa_id.h>
#include <utils/identification.h> #include <utils/identification.h>
@@ -43,14 +42,12 @@ struct connect_manager_t {
* @param id my id * @param id my id
* @param peer_id the other peer's id * @param peer_id the other peer's id
* @param mediated_sa the IKE_SA ID of the mediated connection * @param mediated_sa the IKE_SA ID of the mediated connection
* @param child the CHILD_SA config of the mediated connection
* @returns * @returns
* - TRUE, if there was already a mediated connection registered * - TRUE, if there was already a mediated connection registered
* - FALSE, otherwise * - FALSE, otherwise
*/ */
bool (*check_and_register) (connect_manager_t *this, bool (*check_and_register) (connect_manager_t *this,
identification_t *id, identification_t *peer_id, identification_t *id, identification_t *peer_id, ike_sa_id_t *mediated_sa);
ike_sa_id_t *mediated_sa, child_cfg_t *child);
/** /**
* Checks if there are waiting connections with a specific peer. * Checks if there are waiting connections with a specific peer.
+33 -53
View File
@@ -1030,29 +1030,21 @@ static status_t initiate_mediation(private_ike_sa_t *this, peer_cfg_t *mediated_
* Implementation of ike_sa_t.initiate_mediated * Implementation of ike_sa_t.initiate_mediated
*/ */
static status_t initiate_mediated(private_ike_sa_t *this, host_t *me, host_t *other, static status_t initiate_mediated(private_ike_sa_t *this, host_t *me, host_t *other,
linked_list_t *childs, chunk_t connect_id) chunk_t connect_id)
{ {
set_my_host(this, me->clone(me)); set_my_host(this, me->clone(me));
set_other_host(this, other->clone(other)); set_other_host(this, other->clone(other));
chunk_free(&this->connect_id);
this->connect_id = chunk_clone(connect_id); this->connect_id = chunk_clone(connect_id);
task_t *task;
child_cfg_t *child_cfg;
iterator_t *iterator = childs->create_iterator(childs, TRUE);
while (iterator->iterate(iterator, (void**)&child_cfg))
{
task = (task_t*)child_create_create(&this->public, child_cfg);
this->task_manager->queue_task(this->task_manager, task);
}
iterator->destroy(iterator);
return this->task_manager->initiate(this->task_manager); return this->task_manager->initiate(this->task_manager);
} }
#endif /* ME */ #endif /* ME */
/** /**
* Implementation of ike_sa_t.initiate. * Initiates a CHILD_SA using the appropriate reqid
*/ */
static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg) static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid)
{ {
task_t *task; task_t *task;
@@ -1098,16 +1090,9 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
} }
#ifdef ME #ifdef ME
if (this->peer_cfg->get_mediated_by(this->peer_cfg)) if (this->peer_cfg->is_mediation(this->peer_cfg))
{
/* mediated connection, initiate mediation process */
job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id, child_cfg);
child_cfg->destroy(child_cfg);
charon->processor->queue_job(charon->processor, job);
return SUCCESS;
}
else if (this->peer_cfg->is_mediation(this->peer_cfg))
{ {
/* mediation connection */
if (this->state == IKE_ESTABLISHED) if (this->state == IKE_ESTABLISHED)
{ /* FIXME: we should try to find a better solution to this */ { /* FIXME: we should try to find a better solution to this */
SIG(CHILD_UP_SUCCESS, "mediation connection is already up and running"); SIG(CHILD_UP_SUCCESS, "mediation connection is already up and running");
@@ -1120,22 +1105,43 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
/* normal IKE_SA with CHILD_SA */ /* normal IKE_SA with CHILD_SA */
task = (task_t*)child_create_create(&this->public, child_cfg); task = (task_t*)child_create_create(&this->public, child_cfg);
child_cfg->destroy(child_cfg); child_cfg->destroy(child_cfg);
if (reqid)
{
child_create_t *child_create = (child_create_t*)task;
child_create->use_reqid(child_create, reqid);
}
this->task_manager->queue_task(this->task_manager, task); this->task_manager->queue_task(this->task_manager, task);
#ifdef ME
if (this->peer_cfg->get_mediated_by(this->peer_cfg))
{
/* mediated connection, initiate mediation process */
job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
charon->processor->queue_job(charon->processor, job);
return SUCCESS;
}
#endif /* ME */
} }
return this->task_manager->initiate(this->task_manager); return this->task_manager->initiate(this->task_manager);
} }
/**
* Implementation of ike_sa_t.initiate.
*/
static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
{
return initiate_with_reqid(this, child_cfg, 0);
}
/** /**
* Implementation of ike_sa_t.acquire. * Implementation of ike_sa_t.acquire.
*/ */
static status_t acquire(private_ike_sa_t *this, u_int32_t reqid) static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
{ /* FIXME: IKE-ME */ {
child_cfg_t *child_cfg; child_cfg_t *child_cfg;
iterator_t *iterator; iterator_t *iterator;
child_sa_t *current, *child_sa = NULL; child_sa_t *current, *child_sa = NULL;
task_t *task;
child_create_t *child_create;
if (this->state == IKE_DELETING) if (this->state == IKE_DELETING)
{ {
@@ -1164,36 +1170,10 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
return FAILED; return FAILED;
} }
if (this->state == IKE_CREATED)
{
task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_natd_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_post_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
if (this->peer_cfg->use_mobike(this->peer_cfg))
{
task = (task_t*)ike_mobike_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
}
}
child_cfg = child_sa->get_config(child_sa); child_cfg = child_sa->get_config(child_sa);
child_create = child_create_create(&this->public, child_cfg); child_cfg->get_ref(child_cfg);
child_create->use_reqid(child_create, reqid);
this->task_manager->queue_task(this->task_manager, (task_t*)child_create);
return this->task_manager->initiate(this->task_manager); return initiate_with_reqid(this, child_cfg, reqid);
} }
/** /**
@@ -2472,7 +2452,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_server_reflexive_host = (void (*)(ike_sa_t*,host_t*)) set_server_reflexive_host; this->public.set_server_reflexive_host = (void (*)(ike_sa_t*,host_t*)) set_server_reflexive_host;
this->public.get_connect_id = (chunk_t (*)(ike_sa_t*)) get_connect_id; this->public.get_connect_id = (chunk_t (*)(ike_sa_t*)) get_connect_id;
this->public.initiate_mediation = (status_t (*)(ike_sa_t*,peer_cfg_t*)) initiate_mediation; this->public.initiate_mediation = (status_t (*)(ike_sa_t*,peer_cfg_t*)) initiate_mediation;
this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,linked_list_t*,chunk_t)) initiate_mediated; this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,chunk_t)) initiate_mediated;
this->public.relay = (status_t (*)(ike_sa_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool)) relay; this->public.relay = (status_t (*)(ike_sa_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool)) relay;
this->public.callback = (status_t (*)(ike_sa_t*,identification_t*)) callback; this->public.callback = (status_t (*)(ike_sa_t*,identification_t*)) callback;
this->public.respond = (status_t (*)(ike_sa_t*,identification_t*,chunk_t)) respond; this->public.respond = (status_t (*)(ike_sa_t*,identification_t*,chunk_t)) respond;
+1 -2
View File
@@ -484,14 +484,13 @@ struct ike_sa_t {
* *
* @param me local endpoint (gets cloned) * @param me local endpoint (gets cloned)
* @param other remote endpoint (gets cloned) * @param other remote endpoint (gets cloned)
* @param childs linked list of child_cfg_t of CHILD_SAs (gets cloned)
* @param connect_id connect ID (gets cloned) * @param connect_id connect ID (gets cloned)
* @return * @return
* - SUCCESS if initialization started * - SUCCESS if initialization started
* - DESTROY_ME if initialization failed * - DESTROY_ME if initialization failed
*/ */
status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other, status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
linked_list_t *childs, chunk_t connect_id); chunk_t connect_id);
/** /**
* Relay data from one peer to another (i.e. initiate a * Relay data from one peer to another (i.e. initiate a