diff options
author | Clavister OpenSource <opensource@clavister.com> | 2011-12-09 16:03:37 +0100 |
---|---|---|
committer | Clavister OpenSource <opensource@clavister.com> | 2012-03-20 17:31:14 +0100 |
commit | fbbd439bf9830c5ca8994f4b4549f91abddddbad (patch) | |
tree | 37a5015f0e9b6b1c9e2d1ed23fb0cb90c5d1cacc /src | |
parent | 1390daae15b58848b75d3d7f2d44fc054f3da882 (diff) | |
download | strongswan-fbbd439bf9830c5ca8994f4b4549f91abddddbad.tar.bz2 strongswan-fbbd439bf9830c5ca8994f4b4549f91abddddbad.tar.xz |
Added possibility to send notification if task_manager->process fails
Diffstat (limited to 'src')
-rwxr-xr-x | src/libcharon/sa/task_manager_v1.c | 120 |
1 files changed, 68 insertions, 52 deletions
diff --git a/src/libcharon/sa/task_manager_v1.c b/src/libcharon/sa/task_manager_v1.c index 41cd8a7c6..d557d970e 100755 --- a/src/libcharon/sa/task_manager_v1.c +++ b/src/libcharon/sa/task_manager_v1.c @@ -501,6 +501,66 @@ static status_t build_response(private_task_manager_t *this, message_t *request) } /** + * Send a notify in a separate INFORMATIONAL exchange back to the sender. + */ +static void send_notify_response(private_task_manager_t *this, + message_t *request, notify_type_t type, + chunk_t data, task_t *task) +{ + message_t *response; + packet_t *packet; + host_t *me, *other; + u_int32_t mid; + + if (request && request->get_exchange_type(request) == INFORMATIONAL_V1) + { /* don't respond to INFORMATIONAL requests to avoid a notify war */ + DBG1(DBG_IKE, "ignore malformed INFORMATIONAL request"); + return; + } + + response = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION); + response->set_exchange_type(response, INFORMATIONAL_V1); + response->set_request(response, TRUE); + this->rng->get_bytes(this->rng, sizeof(mid), (void*)&mid); + response->set_message_id(response, mid); + + if (task) + { + /* Let the task build the response */ + if (task->build(task,response) != SUCCESS) + { + response->destroy(response); + return; + } + } + else + { + response->add_notify(response, FALSE, type, data); + } + + me = this->ike_sa->get_my_host(this->ike_sa); + if (me->is_anyaddr(me)) + { + me = request->get_destination(request); + this->ike_sa->set_my_host(this->ike_sa, me->clone(me)); + } + other = this->ike_sa->get_other_host(this->ike_sa); + if (other->is_anyaddr(other)) + { + other = request->get_source(request); + this->ike_sa->set_other_host(this->ike_sa, other->clone(other)); + } + response->set_source(response, me->clone(me)); + response->set_destination(response, other->clone(other)); + if (this->ike_sa->generate_message(this->ike_sa, response, + &packet) == SUCCESS) + { + charon->sender->send(charon->sender, packet); + } + response->destroy(response); +} + +/** * handle an incoming request message */ static status_t process_request(private_task_manager_t *this, @@ -610,6 +670,8 @@ static status_t process_request(private_task_manager_t *this, /* processed, but task needs at least another call to build() */ send_response = TRUE; break; + case FAILED_SEND_ERROR: + send_notify_response(this, NULL, 0, chunk_empty, task); case FAILED: default: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); @@ -684,52 +746,6 @@ static status_t process_response(private_task_manager_t *this, } /** - * Send a notify in a separate INFORMATIONAL exchange back to the sender. - */ -static void send_notify_response(private_task_manager_t *this, - message_t *request, notify_type_t type, - chunk_t data) -{ - message_t *response; - packet_t *packet; - host_t *me, *other; - u_int32_t mid; - - if (request->get_exchange_type(request) == INFORMATIONAL_V1) - { /* don't respond to INFORMATIONAL requests to avoid a notify war */ - DBG1(DBG_IKE, "ignore malformed INFORMATIONAL request"); - return; - } - - response = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION); - response->set_exchange_type(response, INFORMATIONAL_V1); - response->set_request(response, TRUE); - this->rng->get_bytes(this->rng, sizeof(mid), (void*)&mid); - response->set_message_id(response, mid); - response->add_notify(response, FALSE, type, data); - me = this->ike_sa->get_my_host(this->ike_sa); - if (me->is_anyaddr(me)) - { - me = request->get_destination(request); - this->ike_sa->set_my_host(this->ike_sa, me->clone(me)); - } - other = this->ike_sa->get_other_host(this->ike_sa); - if (other->is_anyaddr(other)) - { - other = request->get_source(request); - this->ike_sa->set_other_host(this->ike_sa, other->clone(other)); - } - response->set_source(response, me->clone(me)); - response->set_destination(response, other->clone(other)); - if (this->ike_sa->generate_message(this->ike_sa, response, - &packet) == SUCCESS) - { - charon->sender->send(charon->sender, packet); - } - response->destroy(response); -} - -/** * Parse the given message and verify that it is valid. */ static status_t parse_message(private_task_manager_t *this, message_t *msg) @@ -745,27 +761,27 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg) case NOT_SUPPORTED: DBG1(DBG_IKE, "unsupported exchange type"); send_notify_response(this, msg, - INVALID_EXCHANGE_TYPE, chunk_empty); + INVALID_EXCHANGE_TYPE, chunk_empty, NULL); break; case PARSE_ERROR: DBG1(DBG_IKE, "message parsing failed"); send_notify_response(this, msg, - PAYLOAD_MALFORMED, chunk_empty); + PAYLOAD_MALFORMED, chunk_empty, NULL); break; case VERIFY_ERROR: DBG1(DBG_IKE, "message verification failed"); send_notify_response(this, msg, - PAYLOAD_MALFORMED, chunk_empty); + PAYLOAD_MALFORMED, chunk_empty, NULL); break; case FAILED: DBG1(DBG_IKE, "integrity check failed"); send_notify_response(this, msg, - INVALID_HASH_INFORMATION, chunk_empty); + INVALID_HASH_INFORMATION, chunk_empty, NULL); break; case INVALID_STATE: DBG1(DBG_IKE, "found encrypted message, but no keys available"); send_notify_response(this, msg, - PAYLOAD_MALFORMED, chunk_empty); + PAYLOAD_MALFORMED, chunk_empty, NULL); default: break; } @@ -844,7 +860,7 @@ METHOD(task_manager_t, process_message, status_t, DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N", me, other, notify_type_names, NO_PROPOSAL_CHOSEN); send_notify_response(this, msg, - NO_PROPOSAL_CHOSEN, chunk_empty); + NO_PROPOSAL_CHOSEN, chunk_empty, NULL); return DESTROY_ME; } this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg); |