diff options
Diffstat (limited to 'src/libcharon/sa/ike_sa.c')
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index a4e4028ab..58d24b48c 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -50,6 +50,10 @@ #include <processing/jobs/send_dpd_job.h> #include <processing/jobs/send_keepalive_job.h> #include <processing/jobs/rekey_ike_sa_job.h> +<<<<<<< HEAD +======= +#include <encoding/payloads/unknown_payload.h> +>>>>>>> upstream/4.5.1 #ifdef ME #include <sa/tasks/ike_me.h> @@ -559,6 +563,7 @@ METHOD(ike_sa_t, send_dpd, status_t, time_t diff, delay; delay = this->peer_cfg->get_dpd(this->peer_cfg); +<<<<<<< HEAD if (delay == 0) { @@ -566,6 +571,8 @@ METHOD(ike_sa_t, send_dpd, status_t, return SUCCESS; } +======= +>>>>>>> upstream/4.5.1 if (this->task_manager->busy(this->task_manager)) { /* an exchange is in the air, no need to start a DPD check */ @@ -578,7 +585,11 @@ METHOD(ike_sa_t, send_dpd, status_t, last_in = get_use_time(this, TRUE); now = time_monotonic(NULL); diff = now - last_in; +<<<<<<< HEAD if (diff >= delay) +======= + if (!delay || diff >= delay) +>>>>>>> upstream/4.5.1 { /* to long ago, initiate dead peer detection */ task_t *task; @@ -604,8 +615,16 @@ METHOD(ike_sa_t, send_dpd, status_t, } } /* recheck in "interval" seconds */ +<<<<<<< HEAD job = (job_t*)send_dpd_job_create(this->ike_sa_id); lib->scheduler->schedule_job(lib->scheduler, job, delay - diff); +======= + if (delay) + { + job = (job_t*)send_dpd_job_create(this->ike_sa_id); + lib->scheduler->schedule_job(lib->scheduler, job, delay - diff); + } +>>>>>>> upstream/4.5.1 return SUCCESS; } @@ -680,7 +699,14 @@ METHOD(ike_sa_t, set_state, void, } /* start DPD checks */ +<<<<<<< HEAD send_dpd(this); +======= + if (this->peer_cfg->get_dpd(this->peer_cfg)) + { + send_dpd(this); + } +>>>>>>> upstream/4.5.1 } break; } @@ -825,7 +851,11 @@ METHOD(ike_sa_t, float_ports, void, } METHOD(ike_sa_t, update_hosts, void, +<<<<<<< HEAD private_ike_sa_t *this, host_t *me, host_t *other) +======= + private_ike_sa_t *this, host_t *me, host_t *other, bool force) +>>>>>>> upstream/4.5.1 { bool update = FALSE; @@ -858,7 +888,11 @@ METHOD(ike_sa_t, update_hosts, void, if (!other->equals(other, this->other_host)) { /* update others adress if we are NOT NATed */ +<<<<<<< HEAD if (!has_condition(this, COND_NAT_HERE)) +======= + if (force || !has_condition(this, COND_NAT_HERE)) +>>>>>>> upstream/4.5.1 { set_other_host(this, other->clone(other)); update = TRUE; @@ -891,8 +925,19 @@ METHOD(ike_sa_t, update_hosts, void, METHOD(ike_sa_t, generate_message, status_t, private_ike_sa_t *this, message_t *message, packet_t **packet) { +<<<<<<< HEAD this->stats[STAT_OUTBOUND] = time_monotonic(NULL); message->set_ike_sa_id(message, this->ike_sa_id); +======= + if (message->is_encoded(message)) + { /* already done */ + *packet = message->get_packet(message); + return SUCCESS; + } + this->stats[STAT_OUTBOUND] = time_monotonic(NULL); + message->set_ike_sa_id(message, this->ike_sa_id); + charon->bus->message(charon->bus, message, FALSE); +>>>>>>> upstream/4.5.1 return message->generate(message, this->keymat->get_aead(this->keymat, FALSE), packet); } @@ -901,7 +946,11 @@ METHOD(ike_sa_t, generate_message, status_t, * send a notify back to the sender */ static void send_notify_response(private_ike_sa_t *this, message_t *request, +<<<<<<< HEAD notify_type_t type) +======= + notify_type_t type, chunk_t data) +>>>>>>> upstream/4.5.1 { message_t *response; packet_t *packet; @@ -910,7 +959,11 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request, response->set_exchange_type(response, request->get_exchange_type(request)); response->set_request(response, FALSE); response->set_message_id(response, request->get_message_id(request)); +<<<<<<< HEAD response->add_notify(response, FALSE, type, chunk_empty); +======= + response->add_notify(response, FALSE, type, data); +>>>>>>> upstream/4.5.1 if (this->my_host->is_anyaddr(this->my_host)) { this->my_host->destroy(this->my_host); @@ -1175,6 +1228,10 @@ METHOD(ike_sa_t, process_message, status_t, { status_t status; bool is_request; +<<<<<<< HEAD +======= + u_int8_t type = 0; +>>>>>>> upstream/4.5.1 if (this->state == IKE_PASSIVE) { /* do not handle messages in passive state */ @@ -1185,9 +1242,35 @@ METHOD(ike_sa_t, process_message, status_t, status = message->parse_body(message, this->keymat->get_aead(this->keymat, TRUE)); +<<<<<<< HEAD if (status != SUCCESS) { +======= + if (status == SUCCESS) + { /* check for unsupported critical payloads */ + enumerator_t *enumerator; + unknown_payload_t *unknown; + payload_t *payload; + + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + unknown = (unknown_payload_t*)payload; + type = payload->get_type(payload); + if (!payload_is_known(type) && + unknown->is_critical(unknown)) + { + DBG1(DBG_ENC, "payload type %N is not supported, " + "but its critical!", payload_type_names, type); + status = NOT_SUPPORTED; + } + } + enumerator->destroy(enumerator); + } + if (status != SUCCESS) + { +>>>>>>> upstream/4.5.1 if (is_request) { switch (status) @@ -1196,21 +1279,40 @@ METHOD(ike_sa_t, process_message, status_t, DBG1(DBG_IKE, "critical unknown payloads found"); if (is_request) { +<<<<<<< HEAD send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD); +======= + send_notify_response(this, message, + UNSUPPORTED_CRITICAL_PAYLOAD, + chunk_from_thing(type)); + this->task_manager->incr_mid(this->task_manager, FALSE); +>>>>>>> upstream/4.5.1 } break; case PARSE_ERROR: DBG1(DBG_IKE, "message parsing failed"); if (is_request) { +<<<<<<< HEAD send_notify_response(this, message, INVALID_SYNTAX); +======= + send_notify_response(this, message, + INVALID_SYNTAX, chunk_empty); + this->task_manager->incr_mid(this->task_manager, FALSE); +>>>>>>> upstream/4.5.1 } break; case VERIFY_ERROR: DBG1(DBG_IKE, "message verification failed"); if (is_request) { +<<<<<<< HEAD send_notify_response(this, message, INVALID_SYNTAX); +======= + send_notify_response(this, message, + INVALID_SYNTAX, chunk_empty); + this->task_manager->incr_mid(this->task_manager, FALSE); +>>>>>>> upstream/4.5.1 } break; case FAILED: @@ -1219,10 +1321,13 @@ METHOD(ike_sa_t, process_message, status_t, break; case INVALID_STATE: DBG1(DBG_IKE, "found encrypted message, but no keys available"); +<<<<<<< HEAD if (is_request) { send_notify_response(this, message, INVALID_SYNTAX); } +======= +>>>>>>> upstream/4.5.1 default: break; } @@ -1252,7 +1357,12 @@ METHOD(ike_sa_t, process_message, status_t, /* no config found for these hosts, destroy */ DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N", me, other, notify_type_names, NO_PROPOSAL_CHOSEN); +<<<<<<< HEAD send_notify_response(this, message, NO_PROPOSAL_CHOSEN); +======= + send_notify_response(this, message, + NO_PROPOSAL_CHOSEN, chunk_empty); +>>>>>>> upstream/4.5.1 return DESTROY_ME; } /* add a timeout if peer does not establish it completely */ |