diff options
Diffstat (limited to 'Source/charon/sa')
-rw-r--r-- | Source/charon/sa/ike_sa.c | 56 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.h | 8 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_auth_requested.c | 1 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_requested.c | 1 |
4 files changed, 60 insertions, 6 deletions
diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index a974ce3e8..6abed041c 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -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,16 +198,21 @@ 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 */ logger_t *logger; @@ -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; diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index 6a12aaf8d..b8a897af5 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -281,6 +281,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. * * @param this calling object diff --git a/Source/charon/sa/states/ike_auth_requested.c b/Source/charon/sa/states/ike_auth_requested.c index 82d7ca934..9fe7b1b9f 100644 --- a/Source/charon/sa/states/ike_auth_requested.c +++ b/Source/charon/sa/states/ike_auth_requested.c @@ -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 */ diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index b5ebd1283..ebca25ffc 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -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"); |