- retransmitting of requests implemented
This commit is contained in:
parent
ccb37df25d
commit
0df63d6be4
|
@ -123,6 +123,17 @@ struct private_configuration_manager_t {
|
|||
* Assigned logger object.
|
||||
*/
|
||||
logger_t *logger;
|
||||
|
||||
|
||||
/**
|
||||
* Max number of retransmitted requests.
|
||||
*/
|
||||
u_int32_t max_retransmit_count;
|
||||
|
||||
/**
|
||||
* First retransmit timeout in ms.
|
||||
*/
|
||||
u_int32_t first_retransmit_timeout;
|
||||
|
||||
/**
|
||||
* Load default configuration
|
||||
|
@ -457,6 +468,21 @@ static void add_new_configuration (private_configuration_manager_t *this, char *
|
|||
this->configurations->insert_first(this->configurations,configuration_entry_create(name,init_config,sa_config));
|
||||
}
|
||||
|
||||
static status_t get_retransmit_timeout (private_configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout)
|
||||
{
|
||||
if ((retransmit_count > this->max_retransmit_count) && (this->max_retransmit_count != 0))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO implement a good retransmit policy
|
||||
*/
|
||||
*timeout = this->first_retransmit_timeout * (retransmit_count + 1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_manager_t.destroy.
|
||||
*/
|
||||
|
@ -499,7 +525,7 @@ static void destroy(private_configuration_manager_t *this)
|
|||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
configuration_manager_t *configuration_manager_create()
|
||||
configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count)
|
||||
{
|
||||
private_configuration_manager_t *this = allocator_alloc_thing(private_configuration_manager_t);
|
||||
|
||||
|
@ -509,6 +535,7 @@ configuration_manager_t *configuration_manager_create()
|
|||
this->public.get_init_config_for_host = (status_t (*) (configuration_manager_t *, host_t *, host_t *,init_config_t **)) get_init_config_for_host;
|
||||
this->public.get_sa_config_for_name =(status_t (*) (configuration_manager_t *, char *, sa_config_t **)) get_sa_config_for_name;
|
||||
this->public.get_sa_config_for_init_config_and_id =(status_t (*) (configuration_manager_t *, init_config_t *, identification_t *, identification_t *,sa_config_t **)) get_sa_config_for_init_config_and_id;
|
||||
this->public.get_retransmit_timeout = (status_t (*) (configuration_manager_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout;
|
||||
|
||||
/* private functions */
|
||||
this->load_default_config = load_default_config;
|
||||
|
@ -519,6 +546,8 @@ configuration_manager_t *configuration_manager_create()
|
|||
this->configurations = linked_list_create();
|
||||
this->sa_configs = linked_list_create();
|
||||
this->init_configs = linked_list_create();
|
||||
this->max_retransmit_count = max_retransmit_count;
|
||||
this->first_retransmit_timeout = first_retransmit_timeout;
|
||||
|
||||
this->load_default_config(this);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct configuration_manager_t configuration_manager_t;
|
|||
struct configuration_manager_t {
|
||||
|
||||
/**
|
||||
* Gets the configuration information needed for IKE_SA_INIT exchange
|
||||
* Get the configuration information needed for IKE_SA_INIT exchange
|
||||
* for a specific configuration name.
|
||||
*
|
||||
* The returned init_config_t object MUST NOT be destroyed cause it's the original one.
|
||||
|
@ -55,7 +55,7 @@ struct configuration_manager_t {
|
|||
status_t (*get_init_config_for_name) (configuration_manager_t *this, char *name, init_config_t **init_config);
|
||||
|
||||
/**
|
||||
* Gets the configuration information needed for IKE_SA_INIT exchange
|
||||
* Get the configuration information needed for IKE_SA_INIT exchange
|
||||
* for specific host informations.
|
||||
*
|
||||
* The returned init_config_t object MUST NOT be destroyed cause it's the original one.
|
||||
|
@ -72,7 +72,7 @@ struct configuration_manager_t {
|
|||
status_t (*get_init_config_for_host) (configuration_manager_t *this, host_t *my_host, host_t *other_host,init_config_t **init_config);
|
||||
|
||||
/**
|
||||
* Gets the configuration information needed after IKE_SA_INIT exchange.
|
||||
* Get the configuration information needed after IKE_SA_INIT exchange.
|
||||
*
|
||||
* The returned sa_config_t object MUST not be destroyed cause it's the original one.
|
||||
*
|
||||
|
@ -87,7 +87,7 @@ struct configuration_manager_t {
|
|||
status_t (*get_sa_config_for_name) (configuration_manager_t *this, char *name, sa_config_t **sa_config);
|
||||
|
||||
/**
|
||||
* Gets the configuration information needed after IKE_SA_INIT exchange
|
||||
* Get the configuration information needed after IKE_SA_INIT exchange
|
||||
* for specific init_config_t and ID data.
|
||||
*
|
||||
* The returned sa_config_t object MUST NOT be destroyed cause it's the original one.
|
||||
|
@ -104,6 +104,21 @@ struct configuration_manager_t {
|
|||
*/
|
||||
status_t (*get_sa_config_for_init_config_and_id) (configuration_manager_t *this, init_config_t *init_config, identification_t *other_id, identification_t *my_id,sa_config_t **sa_config);
|
||||
|
||||
/**
|
||||
* Get the retransmit timeout.
|
||||
*
|
||||
* The timeout values are managed by the configuration manager.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param retransmit_count number of times a message was allready retransmitted
|
||||
* @param[out] timeout the new retransmit timeout in milliseconds
|
||||
*
|
||||
* @return
|
||||
* - FAILED if the message should not be resent again
|
||||
* - SUCCESS
|
||||
*/
|
||||
status_t (*get_retransmit_timeout) (configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout);
|
||||
|
||||
/**
|
||||
* Destroys configuration manager
|
||||
*
|
||||
|
@ -118,12 +133,14 @@ struct configuration_manager_t {
|
|||
/**
|
||||
* Creates the mighty configuration manager
|
||||
*
|
||||
* @param first_retransmit_timeout first retransmit timeout in milliseconds
|
||||
* @param max_retransmit_count max number of retransmitted requests (0 for infinite)
|
||||
* @return
|
||||
* - pointer to created manager object if succeeded
|
||||
* - NULL if memory allocation failed
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
configuration_manager_t *configuration_manager_create();
|
||||
configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count);
|
||||
|
||||
#endif /*CONFIGURATION_MANAGER_H_*/
|
||||
|
|
|
@ -174,7 +174,7 @@ static void initialize(private_daemon_t *this)
|
|||
this->public.job_queue = job_queue_create();
|
||||
this->public.event_queue = event_queue_create();
|
||||
this->public.send_queue = send_queue_create();
|
||||
this->public.configuration_manager = configuration_manager_create();
|
||||
this->public.configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT);
|
||||
|
||||
this->public.sender = sender_create();
|
||||
this->public.receiver = receiver_create();
|
||||
|
|
|
@ -52,10 +52,20 @@
|
|||
|
||||
/**
|
||||
* Port on which the daemon will
|
||||
* listen for incoming traffic
|
||||
* listen for incoming traffic.
|
||||
*/
|
||||
#define IKEV2_UDP_PORT 4500
|
||||
|
||||
/**
|
||||
* First retransmit timeout in milliseconds.
|
||||
*/
|
||||
#define RETRANSMIT_TIMEOUT 3000
|
||||
|
||||
/**
|
||||
* Max retransmit count. 0 for infinite.
|
||||
*/
|
||||
#define MAX_RETRANSMIT_COUNT 0
|
||||
|
||||
/**
|
||||
* Default loglevel to use. This is the
|
||||
* maximum allowed level for ever context, the definiton
|
||||
|
|
|
@ -46,6 +46,11 @@ struct private_retransmit_request_job_t {
|
|||
* ID of the IKE_SA which the message belongs to.
|
||||
*/
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
|
||||
/**
|
||||
* Number of times a request was retransmitted
|
||||
*/
|
||||
u_int32_t retransmit_count;
|
||||
};
|
||||
|
||||
|
||||
|
@ -65,6 +70,22 @@ static ike_sa_id_t *get_ike_sa_id(private_retransmit_request_job_t *this)
|
|||
return this->ike_sa_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements retransmit_request_job_t.get_retransmit_count.
|
||||
*/
|
||||
static u_int32_t get_retransmit_count(private_retransmit_request_job_t *this)
|
||||
{
|
||||
return this->retransmit_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements retransmit_request_job_t.increase_retransmit_count.
|
||||
*/
|
||||
static void increase_retransmit_count(private_retransmit_request_job_t *this)
|
||||
{
|
||||
this->retransmit_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements retransmit_request_job_t.get_message_id.
|
||||
*/
|
||||
|
@ -100,9 +121,12 @@ retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id,ike
|
|||
this->public.get_ike_sa_id = (ike_sa_id_t * (*)(retransmit_request_job_t *)) get_ike_sa_id;
|
||||
this->public.get_message_id = (u_int32_t (*)(retransmit_request_job_t *)) get_message_id;
|
||||
this->public.destroy = (void (*)(retransmit_request_job_t *)) destroy;
|
||||
this->public.get_retransmit_count = (u_int32_t (*)(retransmit_request_job_t *)) get_retransmit_count;
|
||||
this->public.increase_retransmit_count = (void (*)(retransmit_request_job_t *)) increase_retransmit_count;
|
||||
|
||||
/* private variables */
|
||||
this->message_id = message_id;
|
||||
this->retransmit_count = 0;
|
||||
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
|
||||
|
||||
return &(this->public);
|
||||
|
|
|
@ -41,6 +41,21 @@ struct retransmit_request_job_t {
|
|||
*/
|
||||
job_t job_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the retransmit count for a specific request.
|
||||
*
|
||||
* @param this calling retransmit_request_job_t object
|
||||
* @return retransmit count of request
|
||||
*/
|
||||
u_int32_t (*get_retransmit_count) (retransmit_request_job_t *this);
|
||||
|
||||
/**
|
||||
* @brief Increases number of retransmitt attemps.
|
||||
*
|
||||
* @param this calling retransmit_request_job_t object
|
||||
*/
|
||||
void (*increase_retransmit_count) (retransmit_request_job_t *this);
|
||||
|
||||
/**
|
||||
* @brief Returns the message_id of the request to be resent
|
||||
*
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <sa/states/initiator_init.h>
|
||||
#include <sa/states/responder_init.h>
|
||||
#include <queues/jobs/delete_ike_sa_job.h>
|
||||
#include <queues/jobs/retransmit_request_job.h>
|
||||
|
||||
|
||||
|
||||
|
@ -197,15 +198,20 @@ struct private_ike_sa_t {
|
|||
} secrets;
|
||||
|
||||
/**
|
||||
* next message id to receive
|
||||
* next message id to receive.
|
||||
*/
|
||||
u_int32_t message_id_in;
|
||||
|
||||
/**
|
||||
* next message id to send
|
||||
* next message id to send.
|
||||
*/
|
||||
u_int32_t message_id_out;
|
||||
|
||||
/**
|
||||
* Last message id which was successfully replied.
|
||||
*/
|
||||
u_int32_t last_replied_message_id;
|
||||
|
||||
/**
|
||||
* a logger for this IKE_SA
|
||||
*/
|
||||
|
@ -430,8 +436,18 @@ status_t retransmit_request (private_ike_sa_t *this, u_int32_t message_id)
|
|||
{
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
if (message_id == this->last_replied_message_id)
|
||||
{
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
packet = this->last_responded_message->get_packet(this->last_responded_message);
|
||||
if (this->last_requested_message == NULL)
|
||||
{
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
packet = this->last_requested_message->get_packet(this->last_requested_message);
|
||||
charon->send_queue->add(charon->send_queue, packet);
|
||||
|
||||
return SUCCESS;
|
||||
|
@ -650,6 +666,8 @@ static status_t send_request (private_ike_sa_t *this,message_t * message)
|
|||
{
|
||||
packet_t *packet;
|
||||
status_t status;
|
||||
retransmit_request_job_t *retransmit_job;
|
||||
u_int32_t timeout;
|
||||
|
||||
if (message->get_message_id(message) != this->message_id_out)
|
||||
{
|
||||
|
@ -678,7 +696,22 @@ static status_t send_request (private_ike_sa_t *this,message_t * message)
|
|||
|
||||
this->logger->log(this->logger, CONTROL|MOST, "replace last requested message with new one");
|
||||
this->last_requested_message = message;
|
||||
|
||||
|
||||
retransmit_job = retransmit_request_job_create(this->message_id_out,this->ike_sa_id);
|
||||
|
||||
status = charon->configuration_manager->get_retransmit_timeout (charon->configuration_manager,retransmit_job->get_retransmit_count(retransmit_job),&timeout);
|
||||
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|MOST, "No retransmit job for message created!");
|
||||
retransmit_job->destroy(retransmit_job);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Request will be retransmitted in %d ms.",timeout);
|
||||
charon->event_queue->add_relative(charon->event_queue,(job_t *) retransmit_job,timeout);
|
||||
}
|
||||
|
||||
/* message counter can now be increased */
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Increase message counter for outgoing messages");
|
||||
this->message_id_out++;
|
||||
|
@ -726,7 +759,15 @@ static status_t send_response (private_ike_sa_t *this,message_t * message)
|
|||
}
|
||||
|
||||
/**
|
||||
* Implementation of protected_ike_sa_t.destroy.
|
||||
* Implementation of protected_ike_sa_t.set_last_replied_message_id.
|
||||
*/
|
||||
static void set_last_replied_message_id (private_ike_sa_t *this,u_int32_t message_id)
|
||||
{
|
||||
this->last_replied_message_id = message_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of protected_ike_sa_t.reset_message_buffers.
|
||||
*/
|
||||
static void reset_message_buffers (private_ike_sa_t *this)
|
||||
{
|
||||
|
@ -747,6 +788,7 @@ static void reset_message_buffers (private_ike_sa_t *this)
|
|||
|
||||
this->message_id_out = 0;
|
||||
this->message_id_in = 0;
|
||||
this->last_replied_message_id = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -879,7 +921,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||
this->protected.get_crypter_responder = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_responder;
|
||||
this->protected.get_signer_responder = (signer_t *(*) (protected_ike_sa_t *)) get_signer_responder;
|
||||
this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers;
|
||||
|
||||
this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t *,u_int32_t)) set_last_replied_message_id;
|
||||
|
||||
/* private functions */
|
||||
this->resend_last_reply = resend_last_reply;
|
||||
this->create_delete_job = create_delete_job;
|
||||
|
@ -897,6 +940,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||
this->last_responded_message = NULL;
|
||||
this->message_id_out = 0;
|
||||
this->message_id_in = 0;
|
||||
this->last_replied_message_id = -1;
|
||||
this->secrets.d_key = CHUNK_INITIALIZER;
|
||||
this->secrets.ai_key = CHUNK_INITIALIZER;
|
||||
this->secrets.ar_key = CHUNK_INITIALIZER;
|
||||
|
|
|
@ -280,6 +280,14 @@ struct protected_ike_sa_t {
|
|||
*/
|
||||
void (*set_new_state) (protected_ike_sa_t *this,state_t *state);
|
||||
|
||||
/**
|
||||
* Sets the last replied message id.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param message_id message id
|
||||
*/
|
||||
void (*set_last_replied_message_id) (protected_ike_sa_t *this,u_int32_t message_id);
|
||||
|
||||
/**
|
||||
* Gets the internal stored initiator crypter_t object.
|
||||
*
|
||||
|
|
|
@ -193,6 +193,7 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *r
|
|||
return status;
|
||||
}
|
||||
|
||||
this->ike_sa->set_last_replied_message_id(this->ike_sa,request->get_message_id(request));
|
||||
this->logger->log(this->logger, CONTROL | MORE, "IKE_AUTH response successfully handled. IKE_SA established.");
|
||||
|
||||
/* create new state */
|
||||
|
|
|
@ -391,6 +391,7 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
|
|||
request->destroy(request);
|
||||
return DELETE_ME;
|
||||
}
|
||||
this->ike_sa->set_last_replied_message_id(this->ike_sa,request->get_message_id(request));
|
||||
|
||||
/* state can now be changed */
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Create next state object");
|
||||
|
|
|
@ -142,7 +142,7 @@ daemon_t *daemon_create()
|
|||
charon->job_queue = job_queue_create();
|
||||
charon->event_queue = event_queue_create();
|
||||
charon->send_queue = send_queue_create();
|
||||
charon->configuration_manager = configuration_manager_create();
|
||||
charon->configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT);
|
||||
charon->sender = NULL;
|
||||
charon->receiver = NULL;
|
||||
charon->scheduler = NULL;
|
||||
|
|
|
@ -153,7 +153,6 @@ static void process_jobs(private_thread_pool_t *this)
|
|||
case RETRANSMIT_REQUEST:
|
||||
{
|
||||
this->process_retransmit_request_job(this, (retransmit_request_job_t*)job);
|
||||
job->destroy(job);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -327,10 +326,13 @@ static void process_delete_ike_sa_job(private_thread_pool_t *this, delete_ike_sa
|
|||
*/
|
||||
static void process_retransmit_request_job(private_thread_pool_t *this, retransmit_request_job_t *job)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
ike_sa_id_t *ike_sa_id = job->get_ike_sa_id(job);
|
||||
u_int32_t message_id = job->get_message_id(job);
|
||||
bool stop_retransmitting = FALSE;
|
||||
u_int32_t timeout;
|
||||
ike_sa_t *ike_sa;
|
||||
status_t status;
|
||||
|
||||
this->worker_logger->log(this->worker_logger, CONTROL|MOST, "checking out IKE SA %lld:%lld, role %s",
|
||||
ike_sa_id->get_initiator_spi(ike_sa_id),
|
||||
|
@ -348,7 +350,8 @@ static void process_retransmit_request_job(private_thread_pool_t *this, retransm
|
|||
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->worker_logger->log(this->worker_logger, CONTROL | MOST, "Message does'nt have to be retransmitted");
|
||||
this->worker_logger->log(this->worker_logger, CONTROL | MOST, "Message doesn't have to be retransmitted");
|
||||
stop_retransmitting = TRUE;
|
||||
}
|
||||
|
||||
this->worker_logger->log(this->worker_logger, CONTROL|MOST, "Checkin IKE SA %lld:%lld, role %s",
|
||||
|
@ -361,11 +364,25 @@ static void process_retransmit_request_job(private_thread_pool_t *this, retransm
|
|||
{
|
||||
this->worker_logger->log(this->worker_logger, ERROR, "Checkin of IKE SA failed!");
|
||||
}
|
||||
/*
|
||||
u_int32_t message_id = message->get_message_id(message);
|
||||
retransmit_request_job_t *new_job = retransmit_request_job_create(message_id,ike_sa_id);
|
||||
charon->event_queue->add_relative(charon->event_queue,(job_t *) new_job,5000);*/
|
||||
|
||||
if (stop_retransmitting)
|
||||
{
|
||||
job->destroy(job);
|
||||
return;
|
||||
}
|
||||
|
||||
job->increase_retransmit_count(job);
|
||||
status = charon->configuration_manager->get_retransmit_timeout (charon->configuration_manager,job->get_retransmit_count(job),&timeout);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->worker_logger->log(this->worker_logger, CONTROL | MOST, "Message will not be anymore retransmitted");
|
||||
job->destroy(job);
|
||||
/*
|
||||
* TODO delete IKE_SA ?
|
||||
*/
|
||||
return;
|
||||
}
|
||||
charon->event_queue->add_relative(charon->event_queue,(job_t *) job,timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue