respecting "keyingtries" parameter on IKE_SA setup
This commit is contained in:
parent
1edf116cfd
commit
fdb9b2bdde
|
@ -224,6 +224,11 @@ struct private_ike_sa_t {
|
|||
/** when IKE_SA gets deleted */
|
||||
u_int32_t delete;
|
||||
} time;
|
||||
|
||||
/**
|
||||
* how many times we have retried so far (keyingtries)
|
||||
*/
|
||||
u_int32_t keyingtry;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -343,6 +348,160 @@ static void set_other_host(private_ike_sa_t *this, host_t *other)
|
|||
this->other_host = other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.send_dpd
|
||||
*/
|
||||
static status_t send_dpd(private_ike_sa_t *this)
|
||||
{
|
||||
send_dpd_job_t *job;
|
||||
time_t diff, delay;
|
||||
|
||||
delay = this->connection->get_dpd_delay(this->connection);
|
||||
|
||||
if (delay == 0)
|
||||
{
|
||||
/* DPD disabled */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (this->task_manager->busy(this->task_manager))
|
||||
{
|
||||
/* an exchange is in the air, no need to start a DPD check */
|
||||
diff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check if there was any inbound traffic */
|
||||
time_t last_in, now;
|
||||
last_in = get_use_time(this, TRUE);
|
||||
now = time(NULL);
|
||||
diff = now - last_in;
|
||||
if (diff >= delay)
|
||||
{
|
||||
/* to long ago, initiate dead peer detection */
|
||||
task_t *task;
|
||||
|
||||
task = (task_t*)ike_dpd_create(TRUE);
|
||||
diff = 0;
|
||||
DBG1(DBG_IKE, "sending DPD request");
|
||||
|
||||
this->task_manager->queue_task(this->task_manager, task);
|
||||
this->task_manager->initiate(this->task_manager);
|
||||
}
|
||||
}
|
||||
/* recheck in "interval" seconds */
|
||||
job = send_dpd_job_create(this->ike_sa_id);
|
||||
charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
|
||||
(delay - diff) * 1000);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.send_keepalive
|
||||
*/
|
||||
static void send_keepalive(private_ike_sa_t *this)
|
||||
{
|
||||
send_keepalive_job_t *job;
|
||||
time_t last_out, now, diff, interval;
|
||||
|
||||
last_out = get_use_time(this, FALSE);
|
||||
now = time(NULL);
|
||||
|
||||
diff = now - last_out;
|
||||
interval = charon->configuration->get_keepalive_interval(charon->configuration);
|
||||
|
||||
if (diff >= interval)
|
||||
{
|
||||
packet_t *packet;
|
||||
chunk_t data;
|
||||
|
||||
packet = packet_create();
|
||||
packet->set_source(packet, this->my_host->clone(this->my_host));
|
||||
packet->set_destination(packet, this->other_host->clone(this->other_host));
|
||||
data.ptr = malloc(1);
|
||||
data.ptr[0] = 0xFF;
|
||||
data.len = 1;
|
||||
packet->set_data(packet, data);
|
||||
charon->send_queue->add(charon->send_queue, packet);
|
||||
DBG1(DBG_IKE, "sending keep alive");
|
||||
diff = 0;
|
||||
}
|
||||
job = send_keepalive_job_create(this->ike_sa_id);
|
||||
charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
|
||||
(interval - diff) * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_state.
|
||||
*/
|
||||
static ike_sa_state_t get_state(private_ike_sa_t *this)
|
||||
{
|
||||
return this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_state.
|
||||
*/
|
||||
static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
|
||||
{
|
||||
DBG1(DBG_IKE, "IKE_SA state change: %N => %N",
|
||||
ike_sa_state_names, this->state,
|
||||
ike_sa_state_names, state);
|
||||
|
||||
if (state == IKE_ESTABLISHED)
|
||||
{
|
||||
job_t *job;
|
||||
u_int32_t now = time(NULL);
|
||||
u_int32_t soft, hard;
|
||||
bool reauth;
|
||||
|
||||
this->time.established = now;
|
||||
/* start DPD checks */
|
||||
send_dpd(this);
|
||||
|
||||
/* schedule rekeying/reauthentication */
|
||||
soft = this->connection->get_soft_lifetime(this->connection);
|
||||
hard = this->connection->get_hard_lifetime(this->connection);
|
||||
reauth = this->connection->get_reauth(this->connection);
|
||||
DBG1(DBG_IKE, "scheduling %s in %ds, maximum lifetime %ds",
|
||||
reauth ? "reauthentication": "rekeying", soft, hard);
|
||||
|
||||
if (soft)
|
||||
{
|
||||
this->time.rekey = now + soft;
|
||||
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, reauth);
|
||||
charon->event_queue->add_relative(charon->event_queue, job,
|
||||
soft * 1000);
|
||||
}
|
||||
|
||||
if (hard)
|
||||
{
|
||||
this->time.delete = now + hard;
|
||||
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
|
||||
charon->event_queue->add_relative(charon->event_queue, job,
|
||||
hard * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.reset
|
||||
*/
|
||||
static void reset(private_ike_sa_t *this)
|
||||
{
|
||||
/* the responder ID is reset, as peer may choose another one */
|
||||
if (this->ike_sa_id->is_initiator(this->ike_sa_id))
|
||||
{
|
||||
this->ike_sa_id->set_responder_spi(this->ike_sa_id, 0);
|
||||
}
|
||||
|
||||
set_state(this, IKE_CREATED);
|
||||
|
||||
this->task_manager->reset(this->task_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update connection host, as addresses may change (NAT)
|
||||
*/
|
||||
|
@ -840,8 +999,20 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
|
|||
switch (this->state)
|
||||
{
|
||||
case IKE_CONNECTING:
|
||||
{
|
||||
/* retry IKE_SA_INIT if we have multiple keyingtries */
|
||||
u_int32_t tries = this->connection->get_keyingtries(this->connection);
|
||||
this->keyingtry++;
|
||||
if (tries == 0 || tries > this->keyingtry)
|
||||
{
|
||||
SIG(IKE_UP_FAILED, "peer not responding, trying again "
|
||||
"(%d/%d) in background ", this->keyingtry + 1, tries);
|
||||
reset(this);
|
||||
return this->task_manager->initiate(this->task_manager);
|
||||
}
|
||||
SIG(IKE_UP_FAILED, "establishing IKE_SA failed, peer not responding");
|
||||
break;
|
||||
}
|
||||
case IKE_REKEYING:
|
||||
SIG(IKE_REKEY_FAILED, "rekeying IKE_SA failed, peer not responding");
|
||||
break;
|
||||
|
@ -936,144 +1107,6 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.send_dpd
|
||||
*/
|
||||
static status_t send_dpd(private_ike_sa_t *this)
|
||||
{
|
||||
send_dpd_job_t *job;
|
||||
time_t diff, delay;
|
||||
|
||||
delay = this->connection->get_dpd_delay(this->connection);
|
||||
|
||||
if (delay == 0)
|
||||
{
|
||||
/* DPD disabled */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (this->task_manager->busy(this->task_manager))
|
||||
{
|
||||
/* an exchange is in the air, no need to start a DPD check */
|
||||
diff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check if there was any inbound traffic */
|
||||
time_t last_in, now;
|
||||
last_in = get_use_time(this, TRUE);
|
||||
now = time(NULL);
|
||||
diff = now - last_in;
|
||||
if (diff >= delay)
|
||||
{
|
||||
/* to long ago, initiate dead peer detection */
|
||||
task_t *task;
|
||||
|
||||
task = (task_t*)ike_dpd_create(TRUE);
|
||||
diff = 0;
|
||||
DBG1(DBG_IKE, "sending DPD request");
|
||||
|
||||
this->task_manager->queue_task(this->task_manager, task);
|
||||
this->task_manager->initiate(this->task_manager);
|
||||
}
|
||||
}
|
||||
/* recheck in "interval" seconds */
|
||||
job = send_dpd_job_create(this->ike_sa_id);
|
||||
charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
|
||||
(delay - diff) * 1000);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.send_keepalive
|
||||
*/
|
||||
static void send_keepalive(private_ike_sa_t *this)
|
||||
{
|
||||
send_keepalive_job_t *job;
|
||||
time_t last_out, now, diff, interval;
|
||||
|
||||
last_out = get_use_time(this, FALSE);
|
||||
now = time(NULL);
|
||||
|
||||
diff = now - last_out;
|
||||
interval = charon->configuration->get_keepalive_interval(charon->configuration);
|
||||
|
||||
if (diff >= interval)
|
||||
{
|
||||
packet_t *packet;
|
||||
chunk_t data;
|
||||
|
||||
packet = packet_create();
|
||||
packet->set_source(packet, this->my_host->clone(this->my_host));
|
||||
packet->set_destination(packet, this->other_host->clone(this->other_host));
|
||||
data.ptr = malloc(1);
|
||||
data.ptr[0] = 0xFF;
|
||||
data.len = 1;
|
||||
packet->set_data(packet, data);
|
||||
charon->send_queue->add(charon->send_queue, packet);
|
||||
DBG1(DBG_IKE, "sending keep alive");
|
||||
diff = 0;
|
||||
}
|
||||
job = send_keepalive_job_create(this->ike_sa_id);
|
||||
charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
|
||||
(interval - diff) * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_state.
|
||||
*/
|
||||
static ike_sa_state_t get_state(private_ike_sa_t *this)
|
||||
{
|
||||
return this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_state.
|
||||
*/
|
||||
static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
|
||||
{
|
||||
DBG1(DBG_IKE, "IKE_SA state change: %N => %N",
|
||||
ike_sa_state_names, this->state,
|
||||
ike_sa_state_names, state);
|
||||
|
||||
if (state == IKE_ESTABLISHED)
|
||||
{
|
||||
job_t *job;
|
||||
u_int32_t now = time(NULL);
|
||||
u_int32_t soft, hard;
|
||||
bool reauth;
|
||||
|
||||
this->time.established = now;
|
||||
/* start DPD checks */
|
||||
send_dpd(this);
|
||||
|
||||
/* schedule rekeying/reauthentication */
|
||||
soft = this->connection->get_soft_lifetime(this->connection);
|
||||
hard = this->connection->get_hard_lifetime(this->connection);
|
||||
reauth = this->connection->get_reauth(this->connection);
|
||||
DBG1(DBG_IKE, "scheduling %s in %ds, maximum lifetime %ds",
|
||||
reauth ? "reauthentication": "rekeying", soft, hard);
|
||||
|
||||
if (soft)
|
||||
{
|
||||
this->time.rekey = now + soft;
|
||||
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, reauth);
|
||||
charon->event_queue->add_relative(charon->event_queue, job,
|
||||
soft * 1000);
|
||||
}
|
||||
|
||||
if (hard)
|
||||
{
|
||||
this->time.delete = now + hard;
|
||||
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
|
||||
charon->event_queue->add_relative(charon->event_queue, job,
|
||||
hard * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_prf.
|
||||
*/
|
||||
|
@ -1613,22 +1646,6 @@ static void enable_natt(private_ike_sa_t *this, bool local)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.reset
|
||||
*/
|
||||
static void reset(private_ike_sa_t *this)
|
||||
{
|
||||
/* the responder ID is reset, as peer may choose another one */
|
||||
if (this->ike_sa_id->is_initiator(this->ike_sa_id))
|
||||
{
|
||||
this->ike_sa_id->set_responder_spi(this->ike_sa_id, 0);
|
||||
}
|
||||
|
||||
set_state(this, IKE_CREATED);
|
||||
|
||||
this->task_manager->reset(this->task_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_virtual_ip
|
||||
*/
|
||||
|
@ -1978,6 +1995,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||
this->my_virtual_ip = NULL;
|
||||
this->other_virtual_ip = NULL;
|
||||
this->dns_servers = linked_list_create();
|
||||
this->keyingtry = 0;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue