stopping connectivity checks on the responders side after receiving an IKE_SA_INIT request with the proper ME_CONNECTID
This commit is contained in:
@@ -1147,7 +1147,8 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
|
|||||||
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->ike_sa_id);
|
||||||
if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs) != SUCCESS)
|
if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs,
|
||||||
|
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);
|
||||||
@@ -1492,6 +1493,33 @@ static status_t set_responder_data(private_connect_manager_t *this,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of connect_manager_t.stop_checks.
|
||||||
|
*/
|
||||||
|
static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id)
|
||||||
|
{
|
||||||
|
check_list_t *checklist;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(this->mutex));
|
||||||
|
|
||||||
|
if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "checklist with id '%B' not found",
|
||||||
|
&connect_id);
|
||||||
|
pthread_mutex_unlock(&(this->mutex));
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG1(DBG_IKE, "removing checklist with id '%B'", &connect_id);
|
||||||
|
|
||||||
|
remove_checklist(this, checklist);
|
||||||
|
check_list_destroy(checklist);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(this->mutex));
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of connect_manager_t.destroy.
|
* Implementation of connect_manager_t.destroy.
|
||||||
*/
|
*/
|
||||||
@@ -1521,6 +1549,7 @@ connect_manager_t *connect_manager_create()
|
|||||||
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;
|
||||||
this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
|
this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
|
||||||
|
this->public.stop_checks = (status_t(*)(connect_manager_t*,chunk_t))stop_checks;
|
||||||
|
|
||||||
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||||
if (this->hasher == NULL)
|
if (this->hasher == NULL)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -92,6 +92,16 @@ struct connect_manager_t {
|
|||||||
status_t (*set_responder_data) (connect_manager_t *this,
|
status_t (*set_responder_data) (connect_manager_t *this,
|
||||||
chunk_t connect_id, chunk_t key, linked_list_t *endpoints);
|
chunk_t connect_id, chunk_t key, linked_list_t *endpoints);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops checks for a checklist. Used after the responder received an IKE_SA_INIT
|
||||||
|
* request which contains a ME_CONNECTID payload.
|
||||||
|
*
|
||||||
|
* @param connect_id the connect ID
|
||||||
|
* @returns
|
||||||
|
* - NOT_FOUND, if the checklist has not been found
|
||||||
|
* - SUCCESS, otherwise
|
||||||
|
*/
|
||||||
|
status_t (*stop_checks) (connect_manager_t *this, chunk_t connect_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a connectivity check
|
* Processes a connectivity check
|
||||||
|
|||||||
+20
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2007 Tobias Brunner
|
* Copyright (C) 2006-2008 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2006 Martin Willi
|
* Copyright (C) 2005-2006 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
@@ -147,6 +147,11 @@ struct private_ike_sa_t {
|
|||||||
* Server reflexive host
|
* Server reflexive host
|
||||||
*/
|
*/
|
||||||
host_t *server_reflexive_host;
|
host_t *server_reflexive_host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect ID
|
||||||
|
*/
|
||||||
|
chunk_t connect_id;
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -942,6 +947,14 @@ static void set_server_reflexive_host(private_ike_sa_t *this, host_t *host)
|
|||||||
this->server_reflexive_host = host;
|
this->server_reflexive_host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ike_sa_t.get_connect_id.
|
||||||
|
*/
|
||||||
|
static chunk_t get_connect_id(private_ike_sa_t *this)
|
||||||
|
{
|
||||||
|
return this->connect_id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.respond
|
* Implementation of ike_sa_t.respond
|
||||||
*/
|
*/
|
||||||
@@ -992,10 +1005,11 @@ 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)
|
linked_list_t *childs, chunk_t connect_id)
|
||||||
{
|
{
|
||||||
this->my_host = me->clone(me);
|
this->my_host = me->clone(me);
|
||||||
this->other_host = other->clone(other);
|
this->other_host = other->clone(other);
|
||||||
|
this->connect_id = chunk_clone(connect_id);
|
||||||
|
|
||||||
task_t *task;
|
task_t *task;
|
||||||
child_cfg_t *child_cfg;
|
child_cfg_t *child_cfg;
|
||||||
@@ -2314,6 +2328,7 @@ static void destroy(private_ike_sa_t *this)
|
|||||||
charon->mediation_manager->remove(charon->mediation_manager, this->ike_sa_id);
|
charon->mediation_manager->remove(charon->mediation_manager, this->ike_sa_id);
|
||||||
}
|
}
|
||||||
DESTROY_IF(this->server_reflexive_host);
|
DESTROY_IF(this->server_reflexive_host);
|
||||||
|
chunk_free(&this->connect_id);
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|
||||||
DESTROY_IF(this->my_host);
|
DESTROY_IF(this->my_host);
|
||||||
@@ -2403,8 +2418,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
#ifdef ME
|
#ifdef ME
|
||||||
this->public.get_server_reflexive_host = (host_t* (*)(ike_sa_t*)) get_server_reflexive_host;
|
this->public.get_server_reflexive_host = (host_t* (*)(ike_sa_t*)) get_server_reflexive_host;
|
||||||
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.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*)) initiate_mediated;
|
this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,linked_list_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;
|
||||||
@@ -2448,6 +2464,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->ike_initiator = FALSE;
|
this->ike_initiator = FALSE;
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
this->server_reflexive_host = NULL;
|
this->server_reflexive_host = NULL;
|
||||||
|
this->connect_id = chunk_empty;
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
+10
-2
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2007 Tobias Brunner
|
* Copyright (C) 2006-2008 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2006 Martin Willi
|
* Copyright (C) 2005-2006 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
@@ -449,6 +449,13 @@ struct ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
void (*set_server_reflexive_host) (ike_sa_t *this, host_t *host);
|
void (*set_server_reflexive_host) (ike_sa_t *this, host_t *host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the connect ID.
|
||||||
|
*
|
||||||
|
* @return connect ID
|
||||||
|
*/
|
||||||
|
chunk_t (*get_connect_id) (ike_sa_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate the mediation of a mediated connection (i.e. initiate a
|
* Initiate the mediation of a mediated connection (i.e. initiate a
|
||||||
* ME_CONNECT exchange).
|
* ME_CONNECT exchange).
|
||||||
@@ -466,12 +473,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 childs linked list of child_cfg_t of CHILD_SAs (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);
|
linked_list_t *childs, 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
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2008 Tobias Brunner
|
||||||
* Copyright (C) 2005-2007 Martin Willi
|
* Copyright (C) 2005-2007 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -266,6 +267,15 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
|
|||||||
|
|
||||||
build_payloads(this, message);
|
build_payloads(this, message);
|
||||||
|
|
||||||
|
#ifdef ME
|
||||||
|
{
|
||||||
|
chunk_t connect_id = this->ike_sa->get_connect_id(this->ike_sa);
|
||||||
|
if (connect_id.ptr)
|
||||||
|
{
|
||||||
|
message->add_notify(message, FALSE, ME_CONNECTID, connect_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ME */
|
||||||
|
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
@@ -290,6 +300,56 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
|
|||||||
}
|
}
|
||||||
randomizer->destroy(randomizer);
|
randomizer->destroy(randomizer);
|
||||||
|
|
||||||
|
#ifdef ME
|
||||||
|
{
|
||||||
|
chunk_t connect_id = chunk_empty;
|
||||||
|
iterator_t *iterator;
|
||||||
|
payload_t *payload;
|
||||||
|
|
||||||
|
/* check for a ME_CONNECTID notify */
|
||||||
|
iterator = message->get_payload_iterator(message);
|
||||||
|
while (iterator->iterate(iterator, (void**)&payload))
|
||||||
|
{
|
||||||
|
if (payload->get_type(payload) == NOTIFY)
|
||||||
|
{
|
||||||
|
notify_payload_t *notify = (notify_payload_t*)payload;
|
||||||
|
notify_type_t type = notify->get_notify_type(notify);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ME_CONNECTID:
|
||||||
|
{
|
||||||
|
chunk_free(&connect_id);
|
||||||
|
connect_id = chunk_clone(notify->get_notification_data(notify));
|
||||||
|
DBG2(DBG_IKE, "received ME_CONNECTID %#B", &connect_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (type < 16383)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "received %N notify error",
|
||||||
|
notify_type_names, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG1(DBG_IKE, "received %N notify",
|
||||||
|
notify_type_names, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
if (connect_id.ptr)
|
||||||
|
{
|
||||||
|
charon->connect_manager->stop_checks(charon->connect_manager,
|
||||||
|
connect_id);
|
||||||
|
chunk_free(&connect_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ME */
|
||||||
|
|
||||||
process_payloads(this, message);
|
process_payloads(this, message);
|
||||||
|
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
|
|||||||
Reference in New Issue
Block a user