aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa/ike_sa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa/ike_sa.c')
-rw-r--r--src/charon/sa/ike_sa.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index fe8e05207..6488cc20c 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -51,8 +51,7 @@
#include <sa/transactions/dead_peer_detection.h>
#include <sa/transactions/rekey_ike_sa.h>
#include <queues/jobs/retransmit_request_job.h>
-#include <queues/jobs/delete_established_ike_sa_job.h>
-#include <queues/jobs/delete_half_open_ike_sa_job.h>
+#include <queues/jobs/delete_ike_sa_job.h>
#include <queues/jobs/send_dpd_job.h>
#include <queues/jobs/send_keepalive_job.h>
#include <queues/jobs/rekey_ike_sa_job.h>
@@ -204,6 +203,16 @@ struct private_ike_sa_t {
} time;
/**
+ * interval to send DPD liveness check
+ */
+ time_t dpd_delay;
+
+ /**
+ * number of retransmit sequences to go through before giving up (keyingtries)
+ */
+ u_int32_t retrans_sequences;
+
+ /**
* List of queued transactions to process
*/
linked_list_t *transaction_queue;
@@ -428,13 +437,19 @@ static status_t transmit_request(private_ike_sa_t *this)
u_int32_t transmitted;
u_int32_t timeout;
transaction_t *transaction = this->transaction_out;
- u_int32_t message_id = transaction->get_message_id(transaction);
+ u_int32_t message_id;
+
+
+ this->logger->log(this->logger, CONTROL,
+ "transmitting request");
transmitted = transaction->requested(transaction);
timeout = charon->configuration->get_retransmit_timeout(charon->configuration,
- transmitted);
+ transmitted,
+ this->retrans_sequences);
if (timeout == 0)
{
+ /* giving up. TODO: check for childrens with dpdaction=hold */
this->logger->log(this->logger, ERROR,
"giving up after %d retransmits, deleting IKE_SA",
transmitted - 1);
@@ -444,8 +459,11 @@ static status_t transmit_request(private_ike_sa_t *this)
status = transaction->get_request(transaction, &request);
if (status != SUCCESS)
{
+ this->logger->log(this->logger, ERROR,
+ "generating request failed");
return status;
}
+ message_id = transaction->get_message_id(transaction);
/* if we retransmit, the request is already generated */
if (transmitted == 0)
{
@@ -484,6 +502,8 @@ static status_t retransmit_request(private_ike_sa_t *this, u_int32_t message_id)
if (this->transaction_out == NULL ||
this->transaction_out->get_message_id(this->transaction_out) != message_id)
{
+ if (this->transaction_out)
+ printf("trans_out->mid = %d, mid = %d\n", this->transaction_out->get_message_id(this->transaction_out), message_id);
/* no retransmit necessary, transaction did already complete */
return SUCCESS;
}
@@ -668,8 +688,7 @@ static status_t process_response(private_ike_sa_t *this, message_t *response)
current = this->transaction_out;
/* check if message ID is that of our currently active transaction */
if (current == NULL ||
- current->get_message_id(current) !=
- response->get_message_id(response))
+ current->get_message_id(current) != response->get_message_id(response))
{
this->logger->log(this->logger, ERROR,
"received response with message ID %d not requested, ignored");
@@ -839,6 +858,8 @@ static status_t initiate(private_ike_sa_t *this,
DESTROY_IF(this->other_host);
this->other_host = connection->get_other_host(connection);
this->other_host = this->other_host->clone(this->other_host);
+ this->retrans_sequences = connection->get_retrans_seq(connection);
+ this->dpd_delay = connection->get_dpd_delay(connection);
this->message_id_out = 1;
ike_sa_init = ike_sa_init_create(&this->public);
@@ -958,6 +979,8 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
this->message_id_out = 1;
ike_sa_init = ike_sa_init_create(&this->public);
ike_sa_init->set_config(ike_sa_init, connection, policy);
+ /* reuse existing reqid */
+ ike_sa_init->set_reqid(ike_sa_init, reqid);
return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
}
case IKE_CONNECTING:
@@ -971,6 +994,8 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
create_child = create_child_sa_create(&this->public);
create_child->set_policy(create_child, policy);
+ /* reuse existing reqid */
+ create_child->set_reqid(create_child, reqid);
return queue_transaction(this, (transaction_t*)create_child, FALSE);
}
default:
@@ -1090,6 +1115,8 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
this->other_host = this->other_host->clone(this->other_host);
}
set_name(this, connection->get_name(connection));
+ this->retrans_sequences = connection->get_retrans_seq(connection);
+ this->dpd_delay = connection->get_dpd_delay(connection);
break;
case IKE_ESTABLISHED:
case IKE_REKEYING:
@@ -1102,6 +1129,7 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
}
child_sa = child_sa_create(0, this->my_host, this->other_host, 0, 0, FALSE);
+ child_sa->set_name(child_sa, policy->get_name(policy));
my_ts = policy->get_my_traffic_selectors(policy, this->my_host);
other_ts = policy->get_other_traffic_selectors(policy, this->other_host);
status = child_sa->add_policies(child_sa, my_ts, other_ts);
@@ -1162,10 +1190,13 @@ static status_t unroute(private_ike_sa_t *this, policy_t *policy)
static status_t send_dpd(private_ike_sa_t *this)
{
send_dpd_job_t *job;
- time_t diff, interval;
- status_t status = SUCCESS;
+ time_t diff;
- interval = charon->configuration->get_dpd_interval(charon->configuration);
+ if (this->dpd_delay == 0)
+ {
+ /* DPD disabled */
+ return SUCCESS;
+ }
if (this->transaction_out)
{
@@ -1179,20 +1210,20 @@ static status_t send_dpd(private_ike_sa_t *this)
last_in = get_time_inbound(this);
now = time(NULL);
diff = now - last_in;
- if (diff >= interval)
+ if (diff >= this->dpd_delay)
{
/* to long ago, initiate dead peer detection */
dead_peer_detection_t *dpd;
this->logger->log(this->logger, CONTROL, "sending DPD request");
dpd = dead_peer_detection_create(&this->public);
- status = queue_transaction(this, (transaction_t*)dpd, FALSE);
+ queue_transaction(this, (transaction_t*)dpd, FALSE);
diff = 0;
}
}
/* recheck in "interval" seconds */
job = send_dpd_job_create(this->ike_sa_id);
charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
- (interval - diff) * 1000);
+ (this->dpd_delay - diff) * 1000);
return SUCCESS;
}
@@ -1657,7 +1688,7 @@ static void set_lifetimes(private_ike_sa_t *this,
if (hard_lifetime)
{
this->time.delete = this->time.established + hard_lifetime;
- job = (job_t*)delete_established_ike_sa_job_create(this->ike_sa_id);
+ job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
charon->event_queue->add_relative(charon->event_queue, job,
hard_lifetime * 1000);
}
@@ -1982,6 +2013,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->time.established = 0;
this->time.rekey = 0;
this->time.delete = 0;
+ this->dpd_delay = 0;
+ this->retrans_sequences = 0;
return &this->public;
}