ike: Add an option to trigger a DPD instead of a NAT keepalive

This is useful on Android where the app might not be able to send
keep-alives if the device is asleep for a while.  If the NAT mapping
has been deleted in the mean time, the NAT-D payloads allow detecting
this and connectivity can be restored by doing a MOBIKE update or
recreating the SA if the peer already deleted it because the client
wasn't reachable.
This commit is contained in:
Tobias Brunner 2020-03-19 13:39:48 +01:00
parent 31298187bf
commit 0d4a5f6af6
2 changed files with 26 additions and 1 deletions

View File

@ -220,6 +220,11 @@ charon.interfaces_use
charon.keep_alive = 20s
NAT keep alive interval.
charon.keep_alive_dpd_margin = 0s
Number of seconds the keep alive interval may be exceeded before a DPD is
sent instead of a NAT keep alive (0 to disable). This is only useful if a
clock is used that includes time spent suspended (e.g. CLOCK_BOOTTIME).
charon.leak_detective.detailed = yes
Includes source file names and line numbers in leak detective output.

View File

@ -236,6 +236,12 @@ struct private_ike_sa_t {
*/
uint32_t keepalive_interval;
/**
* Time the NAT keep alive interval may be exceeded before triggering a DPD
* instead of a NAT keep alive
*/
uint32_t keepalive_dpd_margin;
/**
* The scheduled keep alive job, if any
*/
@ -655,7 +661,19 @@ METHOD(ike_sa_t, send_keepalive, void,
diff = now - last_out;
if (diff >= this->keepalive_interval)
if (this->keepalive_dpd_margin &&
diff > (this->keepalive_interval + this->keepalive_dpd_margin))
{
if (!this->task_manager->busy(this->task_manager))
{
DBG1(DBG_IKE, "sending DPD instead of keep alive %ds after last "
"outbound message", diff);
this->task_manager->queue_dpd(this->task_manager);
this->task_manager->initiate(this->task_manager);
}
diff = 0;
}
else if (diff >= this->keepalive_interval)
{
packet_t *packet;
chunk_t data;
@ -3183,6 +3201,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
.unique_id = ref_get(&unique_id),
.keepalive_interval = lib->settings->get_time(lib->settings,
"%s.keep_alive", KEEPALIVE_INTERVAL, lib->ns),
.keepalive_dpd_margin = lib->settings->get_time(lib->settings,
"%s.keep_alive_dpd_margin", 0, lib->ns),
.retry_initiate_interval = lib->settings->get_time(lib->settings,
"%s.retry_initiate_interval", 0, lib->ns),
.flush_auth_cfg = lib->settings->get_bool(lib->settings,